/***************************************************************************
* Copyright (C) 2003-2007 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
***************************************************************************/
package org.exoplatform.forum.service.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.observation.Event;
import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.ActivityTypeUtils;
import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.commons.utils.ISO8601;
import org.exoplatform.commons.utils.XPathUtils;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.component.ComponentPlugin;
import org.exoplatform.forum.common.CommonUtils;
import org.exoplatform.forum.common.TransformHTML;
import org.exoplatform.forum.common.UserHelper;
import org.exoplatform.forum.common.conf.RoleRulesPlugin;
import org.exoplatform.forum.common.jcr.JCRQueryUtils;
import org.exoplatform.forum.common.jcr.JCRSessionManager;
import org.exoplatform.forum.common.jcr.JCRTask;
import org.exoplatform.forum.common.jcr.KSDataLocation;
import org.exoplatform.forum.common.jcr.KSDataLocation.Locations;
import org.exoplatform.forum.common.jcr.PropertyReader;
import org.exoplatform.forum.common.jcr.SessionManager;
import org.exoplatform.forum.service.BufferAttachment;
import org.exoplatform.forum.service.Category;
import org.exoplatform.forum.service.DataStorage;
import org.exoplatform.forum.service.EmailNotifyPlugin;
import org.exoplatform.forum.service.Forum;
import org.exoplatform.forum.service.ForumAdministration;
import org.exoplatform.forum.service.ForumAttachment;
import org.exoplatform.forum.service.ForumEventQuery;
import org.exoplatform.forum.service.ForumLinkData;
import org.exoplatform.forum.service.ForumNodeTypes;
import org.exoplatform.forum.service.ForumPageList;
import org.exoplatform.forum.service.ForumPrivateMessage;
import org.exoplatform.forum.service.ForumSearchResult;
import org.exoplatform.forum.service.ForumServiceUtils;
import org.exoplatform.forum.service.ForumStatistic;
import org.exoplatform.forum.service.ForumSubscription;
import org.exoplatform.forum.service.InitializeForumPlugin;
import org.exoplatform.forum.service.JCRPageList;
import org.exoplatform.forum.service.LazyPageList;
import org.exoplatform.forum.service.MessageBuilder;
import org.exoplatform.forum.service.Post;
import org.exoplatform.forum.service.PruneSetting;
import org.exoplatform.forum.service.SendMessageInfo;
import org.exoplatform.forum.service.SortSettings;
import org.exoplatform.forum.service.SortSettings.Direction;
import org.exoplatform.forum.service.SortSettings.SortField;
import org.exoplatform.forum.service.Tag;
import org.exoplatform.forum.service.Topic;
import org.exoplatform.forum.service.TopicListAccess;
import org.exoplatform.forum.service.UserProfile;
import org.exoplatform.forum.service.Utils;
import org.exoplatform.forum.service.Watch;
import org.exoplatform.forum.service.cache.CachedDataStorage;
import org.exoplatform.forum.service.conf.CategoryData;
import org.exoplatform.forum.service.conf.ForumData;
import org.exoplatform.forum.service.conf.ForumInitialDataPlugin;
import org.exoplatform.forum.service.conf.PostData;
import org.exoplatform.forum.service.conf.TopicData;
import org.exoplatform.forum.service.conf.UpdateUserProfileJob;
import org.exoplatform.forum.service.filter.model.CategoryFilter;
import org.exoplatform.forum.service.filter.model.ForumFilter;
import org.exoplatform.forum.service.impl.model.PostFilter;
import org.exoplatform.forum.service.impl.model.TopicFilter;
import org.exoplatform.forum.service.impl.model.UserProfileFilter;
import org.exoplatform.forum.service.jcr.listener.CalculateModeratorEventListener;
import org.exoplatform.forum.service.jcr.listener.DeletedUserCalculateEventListener;
import org.exoplatform.forum.service.jcr.listener.StatisticEventListener;
import org.exoplatform.forum.service.search.UnifiedSearchOrder;
import org.exoplatform.forum.service.task.AbstractForumTask.QueryLastPostTask;
import org.exoplatform.forum.service.task.AbstractForumTask.SendNotificationTask;
import org.exoplatform.forum.service.task.QueryLastPostTaskManager;
import org.exoplatform.forum.service.task.SendNotificationTaskManager;
import org.exoplatform.forum.service.user.AutoPruneJob;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.Property;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
import org.exoplatform.services.jcr.util.IdGenerator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.mail.Message;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.scheduler.JobInfo;
import org.exoplatform.services.scheduler.JobSchedulerService;
import org.exoplatform.services.scheduler.PeriodInfo;
import org.exoplatform.ws.frameworks.cometd.ContinuationService;
import org.exoplatform.ws.frameworks.json.impl.JsonGeneratorImpl;
import org.exoplatform.ws.frameworks.json.value.JsonValue;
import org.quartz.JobDataMap;
import org.w3c.dom.Document;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
/**
* JCR implementation of Forum Data Storage
*
* @author hung.nguyen@exoplatform.com
* @author tu.duy@exoplatform.com
* @version $Revision$
*/
@Managed
@NameTemplate({ @Property(key = "service", value = "forum"), @Property(key = "view", value = "storage") })
@ManagedDescription("Data Storage for this forum")
@SuppressWarnings("unchecked")
public class JCRDataStorage implements DataStorage, ForumNodeTypes {
private static final Log LOG = ExoLogger.getLogger(JCRDataStorage.class);
private Map<String, String> serverConfig = new HashMap<String, String>();
private Map<String, Object> infoMap = new HashMap<String, Object>();
final Queue<SendMessageInfo> pendingMessagesQueue = new ConcurrentLinkedQueue<SendMessageInfo>();
private List<RoleRulesPlugin> rulesPlugins = new ArrayList<RoleRulesPlugin>();
private List<InitializeForumPlugin> defaultPlugins = new ArrayList<InitializeForumPlugin>();
private List<ForumInitialDataPlugin> dataPlugins = new ArrayList<ForumInitialDataPlugin>();
private Map<String, Integer> updatingView = new ConcurrentHashMap<String, Integer>();
private Map<String, List<String>> updatingRead = new ConcurrentHashMap<String, List<String>>();
private SessionManager sessionManager;
private KSDataLocation dataLocator;
private String repository;
private String workspace;
private static final Pattern HIGHLIHT_PATTERN = Pattern.compile("(.*)<strong>(.*)</strong>(.*)");
private final ReentrantLock lock = new ReentrantLock();
private DataStorage cachedStorage;
private SendNotificationTaskManager sendNotificationManager;
private QueryLastPostTaskManager queryLastPostManager;
private static final String DOCTYPE_DECLARATION_DISALLOW = "http://apache.org/xml/features/disallow-doctype-decl";
public JCRDataStorage() {
}
public JCRDataStorage(KSDataLocation dataLocator) {
setDataLocator(dataLocator);
}
public DataStorage getCachedDataStorage() {
if (cachedStorage == null) {
cachedStorage = CommonsUtils.getService(DataStorage.class);
}
return cachedStorage;
}
public SendNotificationTaskManager getSendNotificationTaskManager() {
if (sendNotificationManager == null) {
sendNotificationManager = CommonsUtils.getService(SendNotificationTaskManager.class);
}
return sendNotificationManager;
}
public QueryLastPostTaskManager getQueryLastPostTaskManager() {
if (queryLastPostManager == null) {
queryLastPostManager = CommonsUtils.getService(QueryLastPostTaskManager.class);
}
return queryLastPostManager;
}
private void addQueryLastPostTask(String forumPath) {
QueryLastPostTaskManager queryLastPostManager = getQueryLastPostTaskManager();
if (queryLastPostManager != null) {
queryLastPostManager.addTask(new QueryLastPostTask(forumPath));
}
}
@Managed
@ManagedDescription("repository for forum storage")
public String getRepository() {
return repository;
}
@Managed
@ManagedDescription("workspace for the forum storage")
public String getWorkspace() {
return workspace;
}
@Managed
@ManagedDescription("data path for forum storage")
public String getPath() {
return dataLocator.getForumHomeLocation();
}
protected Node getForumHomeNode(SessionProvider sProvider) throws Exception {
String path = dataLocator.getForumHomeLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getForumSystemHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getForumSystemLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getBanIPHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getBanIPLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
protected Node getStatisticHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getStatisticsLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getForumStatisticsNode(SessionProvider sProvider) throws Exception {
String path = dataLocator.getForumStatisticsLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getAdminHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getAdministrationLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
protected Node getUserProfileHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getUserProfilesLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
protected Node getUserProfileNode(SessionProvider sProvider, String userId) throws Exception {
StringBuffer path = new StringBuffer(dataLocator.getUserProfilesLocation()).append("/").append(userId);
return sessionManager.getSession(sProvider).getRootNode().getNode(path.toString());
}
private Node getUserProfileHome() throws Exception {
return getNodeAt(dataLocator.getUserProfilesLocation());
}
private Node getCategoryHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getForumCategoriesLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getTagHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getTagsLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getKSUserAvatarHomeNode() throws Exception {
return getNodeAt(dataLocator.getAvatarsLocation());
}
private Node getForumBanNode(SessionProvider sProvider) throws Exception {
String path = dataLocator.getForumBanIPLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
private Node getBBCodesHome(SessionProvider sProvider) throws Exception {
String path = dataLocator.getBBCodesLocation();
return sessionManager.getSession(sProvider).getRootNode().getNode(path);
}
/**
* Get a Node by path using the current session of {@link JCRSessionManager}.<br>
* Note that a session must have been initalized by {@link JCRSessionManager#openSession() before calling this method
* @param relPath path relative to root node of the workspace
* @return JCR node located at relPath relative path from root node of the current workspace
*/
private Node getNodeAt(String relPath) throws Exception {
return sessionManager.getCurrentSession().getRootNode().getNode(relPath);
}
private Node getNodeAt(SessionProvider sProvider, String relPath) throws Exception {
if (relPath.indexOf(CommonUtils.SLASH) == 0) {
relPath = relPath.substring(1);
} else if (relPath.indexOf(Utils.CATEGORY) == 0) {
relPath = dataLocator.getForumCategoriesLocation() + CommonUtils.SLASH + relPath;
}
return sessionManager.getSession(sProvider).getRootNode().getNode(relPath);
}
public void addPlugin(ComponentPlugin plugin) throws Exception {
try {
if (plugin instanceof EmailNotifyPlugin) {
serverConfig = ((EmailNotifyPlugin) plugin).getServerConfiguration();
}
} catch (Exception e) {
LOG.error("Failed to add plugin", e);
}
}
public void addRolePlugin(ComponentPlugin plugin) throws Exception {
if (plugin instanceof RoleRulesPlugin) {
rulesPlugins.add((RoleRulesPlugin) plugin);
}
}
public void addInitialDefaultDataPlugin(ComponentPlugin plugin) throws Exception {
if (plugin instanceof InitializeForumPlugin) {
defaultPlugins.add((InitializeForumPlugin) plugin);
}
}
public void addInitialDataPlugin(ComponentPlugin plugin) throws Exception {
if (plugin instanceof ForumInitialDataPlugin) {
dataPlugins.add((ForumInitialDataPlugin) plugin);
}
}
public void addDeletedUserCalculateListener() {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Node profileHome = getUserProfileHome(sProvider);
if (profileHome.hasNode(Utils.USER_PROFILE_DELETED)) {
deletedUserCalculateListener(profileHome.getNode(Utils.USER_PROFILE_DELETED));
}
} catch (Exception e) {
LOG.error("Can not add caculation listerner for deleted user", e);
} finally {
sProvider.close();
}
}
protected void deletedUserCalculateListener(Node node) throws Exception {
try {
ObservationManager observation = node.getSession().getWorkspace().getObservationManager();
DeletedUserCalculateEventListener deleteUserListener = new DeletedUserCalculateEventListener();
observation.addEventListener(deleteUserListener, Event.NODE_ADDED | Event.NODE_REMOVED, node.getPath(), false, null, new String[] { Utils.USER_PROFILES_TYPE, EXO_USER_DELETED }, false);
} catch (Exception e) {
LOG.error("Can not add listener for node " + node.getName(), e);
}
}
public void initCategoryListener() {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
ObservationManager observation = sessionManager.getSession(sProvider).getWorkspace().getObservationManager();
//
CalculateModeratorEventListener moderatorListener = new CalculateModeratorEventListener();
observation.addEventListener(moderatorListener, Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_CHANGED, "/", true, null,
new String[] { EXO_CATEGORY_HOME, EXO_FORUM_CATEGORY, EXO_FORUM }, false);
// statistic listener
StatisticEventListener sListener = new StatisticEventListener();
observation.addEventListener(sListener, Event.NODE_ADDED | Event.NODE_REMOVED, "/", true, null, new String[] { EXO_FORUM, EXO_TOPIC }, false);
} catch (Exception e) {
LOG.error("Failed to init category listenner", e);
} finally {
sProvider.close();
}
}
private NodeIterator getNodeIteratorAutoPruneSetting(SessionProvider sProvider, boolean isActive) throws Exception {
StringBuilder pathQuery = new StringBuilder("SELECT * FROM ").append(EXO_PRUNE_SETTING);
if (isActive) {
pathQuery.append(" WHERE ").append(EXO_IS_ACTIVE).append("='true'");
} else {
pathQuery.append(" ORDER BY ").append(EXO_ID).append(ASC);
}
return getNodeIteratorBySQLQuery(sProvider, pathQuery.toString(), 0, 0, false);
}
public void initAutoPruneSchedules() {
RepositoryService repositoryService = getDataLocation().getRepositoryService();
List<RepositoryEntry> entries = repositoryService.getConfig().getRepositoryConfigurations();
String currentRepo = null;
try {
currentRepo = repositoryService.getCurrentRepository().getConfiguration().getName();
for (RepositoryEntry repositoryEntry : entries) {
repositoryService.setCurrentRepositoryName(repositoryEntry.getName());
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorAutoPruneSetting(sProvider, true);
while (iter.hasNext()) {
addOrRemoveSchedule(getPruneSetting(iter.nextNode()));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Could not perform pruning!", e);
}
} finally {
sProvider.close();
}
}
} catch (Exception e) {
LOG.error("Repository is error!", e);
}
if (currentRepo != null) {
try {
repositoryService.setCurrentRepositoryName(currentRepo);
} catch (RepositoryConfigurationException e) {
LOG.error("Could not reset current repository's name", e);
}
}
}
public boolean isAdminRole(String userName) throws Exception {
return isAdminRole(CommonUtils.createSystemProvider(), userName);
}
private boolean isAdminRole(SessionProvider sProvider, String userName) throws Exception {
if (Utils.isEmpty(userName) || UserProfile.USER_GUEST.equals(userName)) {
return false;
}
if (isAdminRoleConfig(userName)) {
return true;
} else {
Node userHome = getUserProfileHome(sProvider);
if (userHome.hasNode(userName)) {
return (new PropertyReader(userHome.getNode(userName)).l(EXO_USER_ROLE, 2) == UserProfile.ADMIN);
}
}
return false;
}
public boolean isAdminRoleConfig(String userName) throws Exception {
if (Utils.isEmpty(userName)) {
return false;
}
for (int i = 0; i < rulesPlugins.size(); ++i) {
List<String> list = new ArrayList<String>();
list.addAll(rulesPlugins.get(i).getRules(Utils.ADMIN_ROLE));
if (list.contains(userName))
return true;
String[] adminrules = Utils.getStringsInList(list);
if (ForumServiceUtils.isModerator(adminrules, userName))
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
public void setDefaultAvatar(String userName) {
Boolean wasReset = sessionManager.executeAndSave(new ResetAvatarTask(userName));
if (LOG.isDebugEnabled()) {
LOG.debug("Avatar for user " + userName + " was " + (wasReset ? "" : "not") + " reset");
}
}
/**
* Task that reset the user avatar
*
* @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a>
* @version $Revision$
*/
public class ResetAvatarTask implements JCRTask<Boolean> {
String username;
public ResetAvatarTask(String username) {
this.username = username;
}
/**
* Remove the nt:file node used as avatar for the given username username is used as the name of the avatar node
*/
public Boolean execute(Session session) throws Exception {
Boolean wasReset = false;
Node ksAvatarHomnode = getKSUserAvatarHomeNode();
if (ksAvatarHomnode.hasNode(username)) {
Node node = ksAvatarHomnode.getNode(username);
if (node.isNodeType(NT_FILE)) {
node.remove();
ksAvatarHomnode.save();
wasReset = true;
}
}
return wasReset;
}
}
/**
* {@inheritDoc}
*/
public ForumAttachment getUserAvatar(String userName) throws Exception {
ForumAttachment avatar = sessionManager.execute(new LoadAvatarTask(userName));
return avatar;
}
/**
* Loads an avatar for a given user
*
* @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a>
* @version $Revision$
*/
class LoadAvatarTask implements JCRTask<ForumAttachment> {
String username;
public LoadAvatarTask(String username) {
this.username = username;
}
/**
* Load the avatar file from JCR. The username is the name of a nt:file node looked inside the avatar home
*
* @see JCRDataStorage#getKSUserAvatarHomeNode()
*/
public ForumAttachment execute(Session session) throws Exception {
Node ksAvatarHomnode = getKSUserAvatarHomeNode();
if (ksAvatarHomnode.hasNode(username)) {
return getAttachment(ksAvatarHomnode.getNode(username));
} else {
return null;
}
}
}
/**
* {@inheritDoc}
*/
public void saveUserAvatar(String userId, ForumAttachment fileAttachment) throws Exception {
Boolean wasNew = sessionManager.executeAndSave(new SaveAvatarTask(userId, fileAttachment));
if (LOG.isDebugEnabled()) {
LOG.error("avatar was " + ((wasNew) ? "added" : "updated") + " for user " + userId + ": " + fileAttachment);
}
}
/**
* Unit of work for saving an Avatar
*
* @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a>
* @version $Revision$
*/
class SaveAvatarTask implements JCRTask<Boolean> {
String userId;
ForumAttachment fileAttachment;
/**
* @param userId
* owner of the avatar
* @param fileAttachment
* file for the avatar picture to save
*/
public SaveAvatarTask(String userId, ForumAttachment fileAttachment) {
this.userId = userId;
this.fileAttachment = fileAttachment;
}
/**
* Create or update an nt:file node represented by the ForumAttachement. All permissions are granted to any on that file (!)
*
* @param session
* unused
*/
public Boolean execute(Session session) throws Exception {
Node ksAvatarHomnode = getKSUserAvatarHomeNode();
Node avatarNode = null;
Boolean wasNew = false;
if (ksAvatarHomnode.hasNode(userId)) {
avatarNode = ksAvatarHomnode.getNode(userId);
} else {
avatarNode = ksAvatarHomnode.addNode(userId, NT_FILE);
wasNew = true;
}
ForumServiceUtils.reparePermissions(avatarNode, "any");
Node nodeContent = null;
if (avatarNode.hasNode(JCR_CONTENT)) {
nodeContent = avatarNode.getNode(JCR_CONTENT);
} else {
nodeContent = avatarNode.addNode(JCR_CONTENT, NT_RESOURCE);
}
nodeContent.setProperty(JCR_MIME_TYPE, fileAttachment.getMimeType());
nodeContent.setProperty(JCR_DATA, fileAttachment.getInputStream());
nodeContent.setProperty(JCR_LAST_MODIFIED, Calendar.getInstance().getTimeInMillis());
return wasNew;
}
}
public void saveForumAdministration(ForumAdministration forumAdministration) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node administrationHome = getAdminHome(sProvider);
Node forumAdminNode;
try {
forumAdminNode = administrationHome.getNode(Utils.FORUMADMINISTRATION);
} catch (PathNotFoundException e) {
forumAdminNode = administrationHome.addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION);
}
forumAdminNode.setProperty(EXO_FORUM_SORT_BY, forumAdministration.getForumSortBy());
forumAdminNode.setProperty(EXO_FORUM_SORT_BY_TYPE, forumAdministration.getForumSortByType());
forumAdminNode.setProperty(EXO_TOPIC_SORT_BY, forumAdministration.getTopicSortBy());
forumAdminNode.setProperty(EXO_TOPIC_SORT_BY_TYPE, forumAdministration.getTopicSortByType());
forumAdminNode.setProperty(EXO_CENSORED_KEYWORD, forumAdministration.getCensoredKeyword());
forumAdminNode.setProperty(EXO_ENABLE_HEADER_SUBJECT, forumAdministration.getEnableHeaderSubject());
forumAdminNode.setProperty(EXO_HEADER_SUBJECT, forumAdministration.getHeaderSubject());
forumAdminNode.setProperty(EXO_NOTIFY_EMAIL_CONTENT, forumAdministration.getNotifyEmailContent());
forumAdminNode.setProperty(EXO_NOTIFY_EMAIL_MOVED, forumAdministration.getNotifyEmailMoved());
if (forumAdminNode.isNew()) {
forumAdminNode.getSession().save();
} else {
forumAdminNode.save();
}
} catch (Exception e) {
LOG.error("Failed to save forum administration.", e);
}
}
public ForumAdministration getForumAdministration() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
ForumAdministration forumAdministration = new ForumAdministration();
try {
Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION);
PropertyReader reader = new PropertyReader(forumAdminNode);
forumAdministration.setForumSortBy(reader.string(EXO_FORUM_SORT_BY));
forumAdministration.setForumSortByType(reader.string(EXO_FORUM_SORT_BY_TYPE));
forumAdministration.setTopicSortBy(reader.string(EXO_TOPIC_SORT_BY));
forumAdministration.setTopicSortByType(reader.string(EXO_TOPIC_SORT_BY_TYPE));
forumAdministration.setCensoredKeyword(reader.string(EXO_CENSORED_KEYWORD));
forumAdministration.setEnableHeaderSubject(reader.bool(EXO_ENABLE_HEADER_SUBJECT));
forumAdministration.setHeaderSubject(reader.string(EXO_HEADER_SUBJECT));
forumAdministration.setNotifyEmailContent(reader.string(EXO_NOTIFY_EMAIL_CONTENT));
forumAdministration.setNotifyEmailMoved(reader.string(EXO_NOTIFY_EMAIL_MOVED));
return forumAdministration;
} catch (PathNotFoundException e) {
return forumAdministration;
}
}
public SortSettings getForumSortSettings() {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node adminHome = getAdminHome(sProvider);
if (adminHome.hasNode(Utils.FORUMADMINISTRATION)) {
Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION);
PropertyReader reader = new PropertyReader(forumAdminNode);
return new SortSettings(reader.string(EXO_FORUM_SORT_BY, SortField.ORDER.toString()),
reader.string(EXO_FORUM_SORT_BY_TYPE, Direction.ASC.toString()));
} else {
Node forumAdminNode = getAdminHome(sProvider).addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION);
forumAdminNode.setProperty(EXO_FORUM_SORT_BY, SortField.ORDER.toString());
forumAdminNode.setProperty(EXO_FORUM_SORT_BY_TYPE, Direction.ASC.toString());
forumAdminNode.getSession().save();
}
return new SortSettings(SortField.ORDER, Direction.ASC);
} catch (Exception e) {
return new SortSettings(SortField.ORDER, Direction.ASC);
}
}
public SortSettings getTopicSortSettings() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION);
PropertyReader reader = new PropertyReader(forumAdminNode);
return new SortSettings(reader.string(EXO_TOPIC_SORT_BY, SortField.LASTPOST.toString()),
reader.string(EXO_TOPIC_SORT_BY_TYPE, Direction.DESC.toString()));
} catch (Exception e) {
Node forumAdminNode = getAdminHome(sProvider).addNode(Utils.FORUMADMINISTRATION, EXO_ADMINISTRATION);
forumAdminNode.getSession().save();
}
return new SortSettings(SortField.LASTPOST, Direction.DESC);
}
public void initDataPlugin() throws Exception {
for (ForumInitialDataPlugin pln : dataPlugins) {
List<ByteArrayInputStream> arrayInputStreams = pln.importData();
if (arrayInputStreams != null) {
for (ByteArrayInputStream bis : arrayInputStreams) {
importXML(dataLocator.getForumHomeLocation(), bis, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
}
}
}
}
public void initDefaultData() throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
Set<String> set = new HashSet<String>();
try {
Node categoryHome = getCategoryHome(sProvider);
if (categoryHome.hasNodes())
return;
List<CategoryData> categories;
String ct = "";
for (InitializeForumPlugin pln : defaultPlugins) {
categories = pln.getForumInitialData().getCategories();
for (CategoryData categoryData : categories) {
Category category = new Category();
category.setCategoryName(categoryData.getName());
category.setDescription(categoryData.getDescription());
category.setOwner(categoryData.getOwner());
this.saveCategory(category, true);
List<ForumData> forums = categoryData.getForums();
for (ForumData forumData : forums) {
Forum forum = new Forum();
forum.setForumName(forumData.getName());
forum.setDescription(forumData.getDescription());
forum.setOwner(forumData.getOwner());
this.saveForum(category.getId(), forum, true);
List<TopicData> topics = forumData.getTopics();
for (TopicData topicData : topics) {
Topic topic = new Topic();
topic.setTopicName(topicData.getName());
ct = topicData.getContent();
ct = StringUtils.replace(ct, "\\n", "<br/>");
ct = Utils.removeCharterStrange(ct);
topic.setDescription(ct);
topic.setOwner(topicData.getOwner());
topic.setIcon(topicData.getIcon());
this.saveTopic(category.getId(), forum.getId(), topic, true, false, new MessageBuilder());
set.add(topic.getOwner());
List<PostData> posts = topicData.getPosts();
for (PostData postData : posts) {
Post post = new Post();
post.setName(postData.getName());
ct = postData.getContent();
ct = StringUtils.replace(ct, "\\n", "<br/>");
ct = Utils.removeCharterStrange(ct);
post.setMessage(ct);
post.setOwner(postData.getOwner());
post.setIcon(postData.getIcon());
MessageBuilder messageBuilder = new MessageBuilder();
messageBuilder.setLink("link");
this.savePost(category.getId(), forum.getId(), topic.getId(), post, true, messageBuilder);
set.add(post.getOwner());
}
}
}
}
}
Node forumStatisticNode = getForumStatisticsNode(sProvider);
PropertyReader reader = new PropertyReader(forumStatisticNode);
forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, (reader.l(EXO_MEMBERS_COUNT) + set.size()));
forumStatisticNode.save();
} catch (Exception e) {
LOG.error("Init default data is failed!!", e);
} finally {
sProvider.close();
}
}
public List<Category> getCategories() {
return getCategories(CommonUtils.EMPTY_STR);
}
private NodeIterator getCategories(SessionProvider sProvider, String strQuery) throws Exception {
String categoryHomePath = "/" + dataLocator.getForumCategoriesLocation();
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM_CATEGORY, categoryHomePath);
//
if (!Utils.isEmpty(strQuery)) {
sqlQuery.append(" AND ").append(strQuery);
}
// order
sqlQuery.append(" ORDER BY ").append(EXO_CATEGORY_ORDER).append(ASC)
.append(", ").append(EXO_CREATED_DATE).append(ASC);
return getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false);
}
private List<Category> getCategories(String strQuery) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Category> categories = new ArrayList<Category>();
try {
NodeIterator iter = getCategories(sProvider, strQuery);
while (iter.hasNext()) {
Node cateNode = iter.nextNode();
try {
categories.add(getCategory(cateNode));
} catch (RepositoryException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to achieve category" + cateNode.getName(), e);
}
}
}
return categories;
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can not get all categories.", e);
}
return categories;
}
}
public Category getCategory(String categoryId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
return getCategory(getCategoryHome(sProvider).getNode(categoryId));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get category, categoryId: " + categoryId, e);
}
return null;
}
}
public Category getCategoryIncludedSpace() {
Category category = getCategory(Utils.CATEGORY_SPACE_ID_PREFIX);
if (category == null) {
List<Category> categories = getCategories(new StringBuffer(EXO_INCLUDED_SPACE).append("='true'").toString());
category = (categories.size() >= 1) ? categories.get(0) : null;
}
return category;
}
public String[] getPermissionTopicByCategory(String categoryId, String type) throws Exception {
String[] canCreated = new String[] { " " };
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node cateNode = getCategoryHome(sProvider).getNode(categoryId);
canCreated = new PropertyReader(cateNode).strings(type, new String[] { "" });
} catch (Exception e) {
LOG.error("Failed to get permission topic by category", e);
}
return canCreated;
}
private Category getCategory(Node cateNode) throws RepositoryException {
Category cat = new Category(cateNode.getName());
cat.setPath(cateNode.getPath());
PropertyReader reader = new PropertyReader(cateNode);
cat.setOwner(reader.string(EXO_OWNER));
cat.setCategoryName(reader.string(EXO_NAME));
cat.setCategoryOrder(reader.l(EXO_CATEGORY_ORDER));
cat.setCreatedDate(reader.date(EXO_CREATED_DATE));
cat.setDescription(reader.string(EXO_DESCRIPTION));
cat.setModifiedBy(reader.string(EXO_MODIFIED_BY));
cat.setModifiedDate(reader.date(EXO_MODIFIED_DATE));
cat.setUserPrivate(reader.strings(EXO_USER_PRIVATE));
cat.setModerators(reader.strings(EXO_MODERATORS));
cat.setForumCount(reader.l(EXO_FORUM_COUNT));
if (cateNode.isNodeType(EXO_FORUM_WATCHING)) {
cat.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING));
}
cat.setViewer(reader.strings(EXO_VIEWER));
cat.setCreateTopicRole(reader.strings(EXO_CREATE_TOPIC_ROLE));
cat.setPoster(reader.strings(EXO_POSTER));
cat.setIncludedSpace(reader.bool(EXO_INCLUDED_SPACE));
if (!cateNode.hasProperty(EXO_INCLUDED_SPACE)) {
try {
if (cateNode.canAddMixin(MIXIN_FORUM_CATEGORY)) {// mix:forumCategory
cateNode.addMixin(MIXIN_FORUM_CATEGORY);
}
cateNode.setProperty(EXO_INCLUDED_SPACE, false);
cateNode.save();
} catch (Exception e) {
LOG.debug(String.format("The category %s has not property exo:includedSpace. Please, excute the forum upgrade plugin.", cateNode.getName()));
}
}
return cat;
}
public void saveCategory(Category category, boolean isNew) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node catNode = null;
try {
Node categoryHome = getCategoryHome(sProvider);
Session session = categoryHome.getSession();
if (isNew) {
catNode = categoryHome.addNode(category.getId(), EXO_FORUM_CATEGORY);
catNode.setProperty(EXO_ID, category.getId());
catNode.setProperty(EXO_OWNER, category.getOwner());
catNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime());
boolean isIncludedSpace = category.isIncludedSpace() || category.getId().equals(Utils.CATEGORY_SPACE_ID_PREFIX);
try {
catNode.setProperty(EXO_INCLUDED_SPACE, isIncludedSpace);
} catch (Exception e) {
catNode.addMixin("mix:forumCategory");
catNode.setProperty(EXO_INCLUDED_SPACE, isIncludedSpace);
}
session.save();
} else {
catNode = categoryHome.getNode(category.getId());
String[] oldcategoryMod = new PropertyReader(catNode).strings(EXO_MODERATORS, new String[] { "" });
catNode.setProperty(EXO_TEMP_MODERATORS, oldcategoryMod);
}
catNode.setProperty(EXO_NAME, category.getCategoryName());
catNode.setProperty(EXO_CATEGORY_ORDER, category.getCategoryOrder());
catNode.setProperty(EXO_DESCRIPTION, category.getDescription());
catNode.setProperty(EXO_MODIFIED_BY, category.getModifiedBy());
catNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime());
catNode.setProperty(EXO_USER_PRIVATE, convertArray(category.getUserPrivate()));
catNode.setProperty(EXO_CREATE_TOPIC_ROLE, convertArray(category.getCreateTopicRole()));
catNode.setProperty(EXO_POSTER, convertArray(category.getPoster()));
catNode.setProperty(EXO_VIEWER, convertArray(category.getViewer()));
category.setPath(catNode.getPath());
session.save();
try {
if ((isNew && category.getModerators().length > 0) || !isNew) {
catNode.setProperty(EXO_MODERATORS, category.getModerators());
session.save();
}
} catch (Exception e) {
LOG.debug("Failed to save category moderators ", e);
}
} catch (Exception e) {
LOG.error("Failed to save category", e);
throw e;
}
}
@Override
public void saveUserPrivateOfCategory(String categoryId, String priInfo) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node cateHome = getCategoryHome(sProvider);
Node cateNode = cateHome.getNode(categoryId);
Set<String> privates = new HashSet<String>(new PropertyReader(cateNode).list(EXO_USER_PRIVATE, new ArrayList<String>()));
privates.add(priInfo);
cateNode.setProperty(EXO_USER_PRIVATE, privates.toArray(new String[privates.size()]));
cateHome.getSession().save();
} catch (Exception e) {
LOG.error("Failed to save user private of category", e);
}
}
public void saveModOfCategory(List<String> moderatorCate, String userId, boolean isAdd) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node cateHome = getCategoryHome(sProvider);
Node cateNode = null;
boolean isAddNew;
List<String> list;
List<String> listTemp;
for (String cateId : moderatorCate) {
isAddNew = true;
try {
cateNode = cateHome.getNode(cateId);
listTemp = Utils.valuesToList(cateNode.getProperty(EXO_MODERATORS).getValues());
list = new ArrayList<String>();
list.addAll(listTemp);
if (isAdd) {
if (list.isEmpty() || (list.size() == 1 && Utils.isEmpty(list.get(0)))) {
list = new ArrayList<String>();
list.add(userId);
} else if (!list.contains(userId)) {
list.add(userId);
} else {
isAddNew = false;
}
if (isAddNew) {
cateNode.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(listTemp));
cateNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list));
}
} else {
if (!list.isEmpty()) {
if (list.contains(userId)) {
list.remove(userId);
if (list.isEmpty())
list.add("");
cateNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list));//
cateNode.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(listTemp));
}
}
}
} catch (Exception e) {
LOG.debug("Failed to save moderater of categoryId: " + cateId, e);
}
}
cateHome.save();
} catch (Exception e) {
LOG.error("Failed to save moderator of category", e);
}
}
public void calculateModerator(String nodePath, boolean isNew) throws Exception {
try {
JCRSessionManager manager = new JCRSessionManager(workspace);
Session session = manager.createSession();
try {
Node node = (Node) session.getItem(nodePath);
if (node.isNodeType(EXO_FORUM) == false && node.isNodeType(EXO_FORUM_CATEGORY) == false) {
return;
}
PropertyReader reader = new PropertyReader(node);
String[] modTemp = reader.strings(EXO_TEMP_MODERATORS, new String[] {});
if (node.isNodeType(EXO_FORUM_CATEGORY)) {
Category category = new Category(node.getName());
category.setCategoryName(reader.string(EXO_NAME));
category.setModerators(reader.strings(EXO_MODERATORS, new String[] {}));
if (isNew || Utils.arraysHaveDifferentContent(modTemp, category.getModerators())) {
updateModeratorInForums(node, category.getModerators());
updateUserProfileModInCategory(session, node, modTemp, category, isNew);
}
} else if (node.isNodeType(EXO_FORUM)) {
Forum forum = new Forum();
forum.setId(node.getName());
forum.setForumName(reader.string(EXO_NAME, ""));
forum.setModerators(reader.strings(EXO_MODERATORS, new String[] {}));
if (isNew || Utils.arraysHaveDifferentContent(modTemp, forum.getModerators())) {
String categoryId = nodePath.substring(nodePath.indexOf(Utils.CATEGORY), nodePath.lastIndexOf("/"));
setModeratorForum(session, forum.getModerators(), modTemp, forum, categoryId, isNew);
}
}
node.setProperty(EXO_TEMP_MODERATORS, new String[] {});
node.save();
} finally {
session.logout();
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("PathNotFoundException category node or forum node not found");
}
}
}
private void updateModeratorInForums(Node cateNode, String[] moderatorCat) throws RepositoryException {
NodeIterator iter = cateNode.getNodes();
List<String> list;
String[] oldModeratoForums;
String[] strModerators;
while (iter.hasNext()) {
list = new ArrayList<String>();
Node node = iter.nextNode();
if (node.isNodeType(EXO_FORUM)) {
oldModeratoForums = new PropertyReader(node).strings(EXO_MODERATORS, new String[] {});
list.addAll(Arrays.asList(oldModeratoForums));
for (int i = 0; i < moderatorCat.length; i++) {
if (!list.contains(moderatorCat[i])) {
list.add(moderatorCat[i]);
}
}
strModerators = Utils.getStringsInList(list);
node.setProperty(EXO_MODERATORS, strModerators);
node.setProperty(EXO_TEMP_MODERATORS, oldModeratoForums);
}
}
cateNode.save();
}
private void updateUserProfileModInCategory(Session session, Node catNode, String[] oldcategoryMod, Category category, boolean isNew) throws Exception {
Node userProfileHomeNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation());
Node userProfileNode;
String categoryId = category.getId(), cateName = category.getCategoryName();
List<String> moderators = ForumServiceUtils.getUserPermission(category.getModerators());
if (!moderators.isEmpty()) {
for (String string : moderators) {
try {
boolean isAdd = true;
userProfileNode = userProfileHomeNode.getNode(string);
List<String> moderateCategory = new ArrayList<String>();
try {
moderateCategory = Utils.valuesToList(userProfileNode.getProperty(EXO_MODERATE_CATEGORY).getValues());
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get list of moderated Category", e);
}
}
for (String string2 : moderateCategory) {
if (string2.indexOf(categoryId) > 0) {
isAdd = false;
break;
}
}
if (isAdd) {
moderateCategory.add(cateName + "(" + categoryId);
userProfileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(moderateCategory));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get user profile ", e);
}
}
}
}
if (!isNew && oldcategoryMod != null && oldcategoryMod.length > 0 && !Utils.isEmpty(oldcategoryMod[0])) {
if (Utils.arraysHaveDifferentContent(oldcategoryMod, category.getModerators())) {
// calculate moderator of category removed
List<String> olds = new ArrayList<String>(Arrays.asList(oldcategoryMod));
String[] mods = category.getModerators();
for (int i = 0; i < mods.length; i++) {
if (olds.contains(mods[i])) {
olds.remove(mods[i]);
}
}
List<String> oldmoderators = ForumServiceUtils.getUserPermission(olds.toArray(new String[olds.size()]));
for (String oldUserId : oldmoderators) {
if (moderators.contains(oldUserId))
continue;
// edit profile of old user.
userProfileNode = userProfileHomeNode.getNode(oldUserId);
List<String> moderateList = new ArrayList<String>();
try {
moderateList = Utils.valuesToList(userProfileNode.getProperty(EXO_MODERATE_CATEGORY).getValues());
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get list of moderated Category", e);
}
}
for (String string2 : moderateList) {
if (string2.indexOf(categoryId) > 0) {
moderateList.remove(string2);
userProfileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(moderateList));
break;
}
}
moderateList = Utils.valuesToList(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues());
NodeIterator iter = catNode.getNodes();
while (iter.hasNext()) {
Node node = iter.nextNode();
if (node.isNodeType(EXO_FORUM)) {
for (String str : moderateList) {
if (str.indexOf(node.getName()) >= 0) {
moderateList.remove(str);
break;
}
}
List<String> forumMode = Utils.valuesToList(node.getProperty(EXO_MODERATORS).getValues());
List<String> forumModeTemp = new ArrayList<String>();
forumModeTemp.addAll(forumMode);
for (String old : olds) {
if (forumMode.contains(old)) {
forumMode.remove(old);
}
}
node.setProperty(EXO_MODERATORS, Utils.getStringsInList(forumMode));
node.setProperty(EXO_TEMP_MODERATORS, Utils.getStringsInList(forumModeTemp));
}
}
catNode.save();
if (moderateList.isEmpty() || (moderateList.size() == 1 && Utils.isEmpty(moderateList.get(0)))) {
//hasRole == fasle or hasRole =true && is Moderator = true;
if (userProfileNode.hasProperty(EXO_USER_ROLE) == false
|| userProfileNode.hasProperty(EXO_USER_ROLE)
&& userProfileNode.getProperty(EXO_USER_ROLE).getLong() == UserProfile.MODERATOR) {
userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.USER);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.USER);
}
} else {
// moderator > 0
userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.MODERATOR);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR);
}
userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(moderateList));
}
}
}
if (userProfileHomeNode.isNew()) {
session.save();
} else {
userProfileHomeNode.save();
}
}
public Category removeCategory(String categoryId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
Node categoryNode = categoryHome.getNode(categoryId);
Map<String, Long> userPostMap = getDeletePostByUser(sProvider, categoryNode);
Category category = getCategory(categoryNode);
Set<String> users = new HashSet<String>();
PropertyReader reader;
try {
reader = new PropertyReader(categoryNode);
users.addAll(reader.list(EXO_MODERATORS, new ArrayList<String>()));
categoryNode.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[] { "" }));
categoryNode.setProperty(EXO_MODERATORS, new String[] { "" });
NodeIterator iter = categoryNode.getNodes();
while (iter.hasNext()) {
Node node = iter.nextNode();
if (node.isNodeType(EXO_FORUM)) {
reader = new PropertyReader(node);
users.addAll(reader.list(EXO_MODERATORS, new ArrayList<String>()));
node.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[] { "" }));
node.setProperty(EXO_MODERATORS, new String[] { "" });
}
}
categoryNode.save();
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get list of moderators", e);
}
}
categoryNode.remove();
categoryHome.save();
addUpdateUserProfileJob(userPostMap);
getTotalJobWatting(sProvider, users);
return category;
} catch (Exception e) {
LOG.error("failed to remove category " + categoryId);
return null;
}
}
@Deprecated
public List<Forum> getForums(String categoryId, String strQuery) throws Exception {
return getForums(new ForumFilter(categoryId, false).strQuery(strQuery));
}
@Deprecated
public List<Forum> getForumSummaries(String categoryId, String strQuery) throws Exception {
return getForums(new ForumFilter(categoryId, true).strQuery(strQuery));
}
private List<Forum> getForumsPublic(ForumFilter filter) {
StringBuilder sqlQuery = new StringBuilder();
sqlQuery.append(Utils.getSQLQueryByProperty("", EXO_IS_CLOSED, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_LOCK, "false"));
return getForums(filter, sqlQuery.toString());
}
private List<Forum> getForumsOfCategoryByUser(ForumFilter filter) {
try {
StringBuilder sqlQuery = new StringBuilder();
if (Utils.CATEGORY_SPACE_ID_PREFIX.equals(filter.categoryId())) {
if (UserProfile.USER_GUEST.equals(filter.userId())) {
return new ArrayList<Forum>();
}
String querySpace = Utils.buildSQLQueryForumInSpaceOfUser(filter.userId());
if (Utils.isEmpty(querySpace)) {
return new ArrayList<Forum>();
} else {
sqlQuery.append(querySpace);
}
}
boolean isAdmin = getCachedDataStorage().isAdminRole(filter.userId());
if (!isAdmin) {
sqlQuery.append((sqlQuery.length() == 0) ? "(" : " AND (")
.append(Utils.getSQLQueryByProperty("", EXO_IS_CLOSED, "false"))
.append(" OR (")
.append(Utils.buildSQLByUserInfo(EXO_MODERATORS, UserHelper.getAllGroupAndMembershipOfUser(filter.userId())))
.append("))");
}
return getForums(filter, sqlQuery.toString());
} catch (Exception e) {
LOG.warn(String.format("Failed to get forums of category %s by user %s", filter.categoryId(), filter.userId()), e);
}
return new ArrayList<Forum>();
}
@Override
public List<Forum> getForums(ForumFilter filter) {
if (Utils.isEmpty(filter.userId()) == false) {
return getForumsOfCategoryByUser(filter);
} else if (filter.isPublic()) {
return getForumsPublic(filter);
} else {
return getForums(filter, filter.strQuery());
}
}
private List<Forum> getForums(ForumFilter filter, String strQuery) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
SortSettings sort = getForumSortSettings();
SortField orderBy = sort.getField();
Direction orderType = sort.getDirection();
Node catNode = getCategoryHome(sProvider).getNode(filter.categoryId());
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM, catNode.getPath());
if (!Utils.isEmpty(strQuery)) {
sqlQuery.append(" AND ").append(strQuery);
}
// order
sqlQuery.append(" ORDER BY exo:").append(orderBy).append(" ").append(orderType);
if (orderBy != SortField.ORDER) {
sqlQuery.append(", ").append(EXO_FORUM_ORDER).append(ASC);
if (orderBy != SortField.CREATED) {
sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC);
}
} else {
sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC);
}
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), filter.offset(), filter.limit(), true);
List<Forum> forums = new ArrayList<Forum>();
DataStorage storage = getCachedDataStorage();
while (iter.hasNext()) {
Node forumNode = null;
try {
forumNode = iter.nextNode();
forums.add(storage.getForum(filter.categoryId(), forumNode.getName()));
} catch (Exception e) {
LOG.debug("Failed to load forum node " + forumNode.getPath(), e);
}
}
return forums;
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to retrieving forums for category " + filter.categoryId(), e);
}
return new ArrayList<Forum>();
}
}
private List<String> getCategoriesCanCreateTopics(SessionProvider sProvider, List<String> listOfUser, boolean isIgnoreSpace) throws Exception {
Set<String> canCreateTopicIds = new HashSet<String>();
// get all categories not in space that user can create topics
StringBuilder cateBuilder = new StringBuilder();
if (isIgnoreSpace) {
cateBuilder.append(EXO_ID).append(" <> '").append(Utils.CATEGORY_SPACE_ID_PREFIX).append("'");
}
cateBuilder.append((isIgnoreSpace) ? " AND " : "").append(getCanCreateTopicQuery(listOfUser, true));
NodeIterator iter = getCategories(sProvider, cateBuilder.toString());
while (iter.hasNext()) {
canCreateTopicIds.add(iter.nextNode().getName());
}
return new ArrayList<String>(canCreateTopicIds);
}
private String getCanCreateTopicQuery(List<String> listOfUser, boolean isForCategory) {
StringBuilder strQuery = new StringBuilder("( (")
.append(Utils.buildSQLByUserInfo(EXO_CREATE_TOPIC_ROLE, listOfUser))
.append(") OR (").append(Utils.buildSQLByUserInfo(EXO_MODERATORS, listOfUser))
.append(") OR (").append(Utils.buildSQLHasProperty(EXO_CREATE_TOPIC_ROLE));
strQuery.append(") )");
if(isForCategory) {
strQuery.append(" AND (").append(Utils.buildSQLByUserInfo(EXO_USER_PRIVATE, listOfUser))
.append(" OR ").append(Utils.buildSQLHasProperty(EXO_USER_PRIVATE))
.append(")");
}
return strQuery.toString();
}
public List<CategoryFilter> filterForumByName(String forumNameFilter, String userName, int maxSize) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(userName);
//removes all of group what contains "spaces" group
List<String> userListWithoutSpace = new ArrayList<String>();
for(String group : listOfUser) {
if (group != null && group.indexOf(Utils.CATEGORY_SPACE) == -1) {
userListWithoutSpace.add(group);
}
}
// get can create topic
List<String> categoriesCanCreateTopics = getCategoriesCanCreateTopics(sProvider, listOfUser, true);
// query forum by input-key
StringBuffer strQuery = new StringBuffer("SELECT * FROM ");
strQuery.append(EXO_FORUM).append(" WHERE ").append(JCR_PATH).append(" LIKE '").append(categoryHome.getPath()).append("/%' AND ");
strQuery.append("( UPPER(").append(EXO_NAME).append(") LIKE '").append(forumNameFilter.toUpperCase())
.append("%' OR UPPER(").append(EXO_NAME).append(") LIKE '% ").append(forumNameFilter.toUpperCase()).append("%')")
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_LOCK, "false"))
.append(" AND ").append(getCanCreateTopicQuery(userListWithoutSpace, false))
.append(" ORDER BY ").append(EXO_NAME);
LOG.debug("SQL statement: " + strQuery.toString());
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(strQuery.toString(), Query.SQL);
QueryImpl queryImpl = (QueryImpl) query;
queryImpl.setCaseInsensitiveOrder(true);
LinkedHashMap<String, CategoryFilter> categoryFilters = new LinkedHashMap<String, CategoryFilter>();
CategoryFilter categoryFilter;
String categoryId, categoryName, forumId, forumName;
long gotItemNumber = 0;
//
NodeIterator iter = queryImpl.execute().getNodes();
//
while (iter.hasNext()) {
Node node = iter.nextNode();
categoryId = node.getParent().getName();
if (Utils.CATEGORY_SPACE_ID_PREFIX.equalsIgnoreCase(categoryId)) {
continue;
}
forumId = node.getName();
// can create topic in category/forum
if (categoriesCanCreateTopics.contains(categoryId)) {
if (categoryFilters.containsKey(categoryId)) {
categoryFilter = categoryFilters.get(categoryId);
} else {
categoryName = node.getParent().getProperty(EXO_NAME).getString();
categoryFilter = new CategoryFilter(categoryId, categoryName);
categoryFilters.put(categoryId, categoryFilter);
}
forumName = node.getProperty(EXO_NAME).getString();
if (categoryFilter.setForumFilter(forumId, forumName)) {
gotItemNumber++;
if (gotItemNumber == maxSize) {
break;
}
}
}
}
return Collections.unmodifiableList(new ArrayList<CategoryFilter>(categoryFilters.values()));
} catch (Exception e) {
LOG.warn("\nCould not filter forum by name: " + forumNameFilter + "::"+ e.getMessage());
if (LOG.isDebugEnabled()) {
LOG.debug("\nCould not filter forum by name: " + forumNameFilter + e.getCause());
}
}
return Collections.emptyList();
}
public Forum getForum(String categoryId, String forumId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId);
return getForum(forumNode);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("\nCould not get " + forumId + " in " + categoryId + " fail: " + e.getCause());
}
return null;
}
}
public void modifyForum(Forum forum, int type) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumHomeNode = getForumHomeNode(sProvider);
String forumPath = forum.getPath();
Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath);
switch (type) {
case Utils.CLOSE: {
forumNode.setProperty(EXO_IS_CLOSED, forum.getIsClosed());
setActiveTopicByForum(sProvider, forumNode, forum.getIsClosed());
break;
}
case Utils.LOCK: {
forumNode.setProperty(EXO_IS_LOCK, forum.getIsLock());
break;
}
default:
break;
}
forumNode.getSession().save();
} catch (RepositoryException e) {
LOG.error("Failed to modify forum " + forum.getForumName(), e);
}
}
/**
* Update the exo:moderators of a Node. Avoids duplicate.
*
* @param node Forum node
* @param mods list of values to add
* @return The merged list of moderators without duplicates
* @throws Exception
*/
String[] updateModeratorInForum(Node node, String[] mods) throws Exception {
PropertyReader reader = new PropertyReader(node);
Set<String> set = reader.set(EXO_MODERATORS);
if (set == null || set.contains("")) {
return mods;
}
for (String mod : mods) {
if (!mod.isEmpty()) {
set.add(mod);
}
}
return set.toArray(new String[set.size()]);
}
public void saveForum(String categoryId, Forum forum, boolean isNew) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node forumNode = null;
String[] strModerators = forum.getModerators();
try {
Node catNode = getCategoryHome(sProvider).getNode(categoryId);
boolean isNewModerateTopic = forum.getIsModerateTopic();
boolean isModerateTopic = isNewModerateTopic;
String[] oldMod = new String[] {};
if (isNew) {
forumNode = catNode.addNode(forum.getId(), EXO_FORUM);
forumNode.setProperty(EXO_ID, forum.getId());
forumNode.setProperty(EXO_OWNER, forum.getOwner());
forumNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime());
forumNode.setProperty(EXO_LAST_TOPIC_PATH, forum.getLastTopicPath());
forumNode.setProperty(EXO_POST_COUNT, 0);
forumNode.setProperty(EXO_TOPIC_COUNT, 0);
forumNode.setProperty(EXO_BAN_I_PS, new String[] {});
forum.setPath(forumNode.getPath());
long forumCount = 1;
if (catNode.hasProperty(EXO_FORUM_COUNT))
forumCount = catNode.getProperty(EXO_FORUM_COUNT).getLong() + 1;
catNode.setProperty(EXO_FORUM_COUNT, forumCount);
forumNode.setProperty(EXO_MODERATORS, strModerators);
} else {
forumNode = catNode.getNode(forum.getId());
oldMod = Utils.valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues());
forumNode.setProperty(EXO_MODERATORS, strModerators);
forumNode.setProperty(EXO_TEMP_MODERATORS, oldMod);
if (forumNode.hasProperty(EXO_IS_MODERATE_TOPIC))
isModerateTopic = forumNode.getProperty(EXO_IS_MODERATE_TOPIC).getBoolean();
}
forumNode.setProperty(EXO_NAME, forum.getForumName());
forumNode.setProperty(EXO_FORUM_ORDER, forum.getForumOrder());
forumNode.setProperty(EXO_MODIFIED_BY, forum.getModifiedBy());
forumNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime());
forumNode.setProperty(EXO_DESCRIPTION, forum.getDescription());
forumNode.setProperty(EXO_IS_AUTO_ADD_EMAIL_NOTIFY, forum.getIsAutoAddEmailNotify());
forumNode.setProperty(EXO_NOTIFY_WHEN_ADD_POST, forum.getNotifyWhenAddPost());
forumNode.setProperty(EXO_NOTIFY_WHEN_ADD_TOPIC, forum.getNotifyWhenAddTopic());
forumNode.setProperty(EXO_IS_MODERATE_TOPIC, isNewModerateTopic);
forumNode.setProperty(EXO_IS_MODERATE_POST, forum.getIsModeratePost());
forumNode.setProperty(EXO_IS_CLOSED, forum.getIsClosed());
forumNode.setProperty(EXO_IS_LOCK, forum.getIsLock());
forumNode.setProperty(EXO_CREATE_TOPIC_ROLE, convertArray(forum.getCreateTopicRole()));
forumNode.setProperty(EXO_POSTER, convertArray(forum.getPoster()));
// set from category
strModerators = updateModeratorInForum(catNode, strModerators);
boolean isEditMod = isNew;
if (!isNew && Utils.arraysHaveDifferentContent(oldMod, strModerators)) {
isEditMod = true;
}
// save list moderators in property categoryPrivate when list userPrivate of parent category not empty.
if (isEditMod) {
if (strModerators != null && strModerators.length > 0 && !Utils.isEmpty(strModerators[0])) {
if (catNode.hasProperty(EXO_USER_PRIVATE)) {
List<String> listPrivate = new ArrayList<String>();
listPrivate.addAll(Utils.valuesToList(catNode.getProperty(EXO_USER_PRIVATE).getValues()));
if (listPrivate.size() > 0 && !Utils.isEmpty(listPrivate.get(0))) {
for (int i = 0; i < strModerators.length; i++) {
if (!listPrivate.contains(strModerators[i])) {
listPrivate.add(strModerators[i]);
}
}
catNode.setProperty(EXO_USER_PRIVATE, listPrivate.toArray(new String[listPrivate.size()]));
}
}
}
}
forumNode.setProperty(EXO_VIEWER, convertArray(forum.getViewer()));
catNode.getSession().save();
PropertyReader reader = new PropertyReader(forumNode);
forum.setPath(forumNode.getPath());
forum.setTopicCount(reader.l(EXO_TOPIC_COUNT));
forum.setPostCount(reader.l(EXO_POST_COUNT));
forum.setLastTopicPath(getLastTopicPath(reader, forum));
forum.setModerators(strModerators);
StringBuilder id = new StringBuilder();
id.append(catNode.getProperty(EXO_CATEGORY_ORDER).getString());
id.append(catNode.getProperty(EXO_CREATED_DATE).getDate().getTimeInMillis());
id.append(forum.getForumOrder());
if (isNew) {
id.append(getGreenwichMeanTime());
PruneSetting pruneSetting = new PruneSetting();
pruneSetting.setId(id.toString());
pruneSetting.setForumPath(forum.getPath());
savePruneSetting(pruneSetting);
} else {
id.append(forum.getCreatedDate().getTime());
if (isModerateTopic != isNewModerateTopic) {
//
addQueryLastPostTask(forumNode.getPath());
}
// updatePruneId
Node pruneSetting = forumNode.getNode(Utils.PRUNESETTING);
pruneSetting.setProperty(EXO_ID, id.toString());
pruneSetting.save();
}
} catch (Exception e) {
LOG.error("Failed to save forum " + forum.getForumName(), e);
}
}
/**
* Converts the arrays String what has NULL or EMPTY to ""
* It will be applied for these cases such as categories, forums, and topics with fields:
* exo:userPrivate, exo:viewer, exo:canView, exo:createTopicRole, exo:poster, exo:canPost
*
* @param strs
* @return
*/
private static String[] convertArray(String[] strs) {
if (Utils.isEmpty(strs)) {
return new String[] { "" };
}
return strs;
}
private void setModeratorForum(Session session, String[] strModerators, String[] oldModeratoForums, Forum forum, String categoryId, boolean isNew) throws Exception {
Node userProfileHomeNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation());
Node userProfileNode;
List<String> moderators = ForumServiceUtils.getUserPermission(strModerators);
if (moderators.size() > 0) {
for (String string : moderators) {
string = string.trim();
List<String> list = new ArrayList<String>();
try {
userProfileNode = userProfileHomeNode.getNode(string);
List<String> moderatorForums = new ArrayList<String>();
if (userProfileNode.hasProperty(EXO_MODERATE_FORUMS)) {
moderatorForums = PropertyReader.valuesToList(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues());
}
boolean hasMod = false;
for (String string2 : moderatorForums) {
if (string2.indexOf(forum.getId()) > 0) {
hasMod = true;
}
if (!Utils.isEmpty(string2)) {
list.add(string2);
}
}
if (userProfileNode.getProperty(EXO_USER_ROLE).getLong() >= 2) {
userProfileNode.setProperty(EXO_USER_ROLE, 1);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR);
}
if (!hasMod) {
list.add(forum.getForumName() + "(" + categoryId + "/" + forum.getId());
userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(list));
getTotalJobWaitingForModerator(session, string);
}
} catch (PathNotFoundException e) {
userProfileNode = userProfileHomeNode.addNode(string, EXO_FORUM_USER_PROFILE);
String[] strings = new String[] { (forum.getForumName() + "(" + categoryId + "/" + forum.getId()) };
userProfileNode.setProperty(EXO_MODERATE_FORUMS, strings);
userProfileNode.setProperty(EXO_USER_ROLE, 1);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR);
if (userProfileNode.isNew()) {
userProfileNode.getSession().save();
} else {
userProfileNode.save();
}
getTotalJobWaitingForModerator(session, string);
}
}
}
// remove
if (!isNew) {
List<String> oldmoderators = ForumServiceUtils.getUserPermission(oldModeratoForums);
for (String string : oldmoderators) {
boolean isDelete = true;
if (moderators.contains(string)) {
isDelete = false;
}
if (isDelete) {
try {
List<String> list = new ArrayList<String>();
userProfileNode = userProfileHomeNode.getNode(string);
String[] moderatorForums = PropertyReader.valuesToArray(userProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues());
for (String string2 : moderatorForums) {
if (string2.indexOf(forum.getId()) < 0) {
list.add(string2);
}
}
userProfileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(list));
if (list.isEmpty()) {
//hasRole == fasle or hasRole =true && is Moderator = true;
if (userProfileNode.hasProperty(EXO_USER_ROLE) == false
|| userProfileNode.hasProperty(EXO_USER_ROLE)
&& userProfileNode.getProperty(EXO_USER_ROLE).getLong() == UserProfile.MODERATOR) {
userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.USER);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.USER);
}
} else {
// moderator > 0
userProfileNode.setProperty(EXO_USER_ROLE, UserProfile.MODERATOR);
userProfileNode.setProperty(EXO_USER_TITLE, Utils.MODERATOR);
}
} catch (Exception e) {
logDebug("Failed to removing forumId storage in property moderator of user: " + string);
}
}
}
}
if (userProfileHomeNode.isNew()) {
userProfileHomeNode.getSession().save();
} else {
userProfileHomeNode.save();
}
}
public void saveModerateOfForums(List<String> forumPaths, String userName, boolean isDelete) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node categoryHomeNode = getCategoryHome(sProvider);
for (String path : forumPaths) {
String forumPath = categoryHomeNode.getPath() + "/" + path;
Node forumNode;
try {
forumNode = (Node) categoryHomeNode.getSession().getItem(forumPath);
Node cateNode = forumNode.getParent();
if (isDelete) {
String[] cateMods = PropertyReader.valuesToArray(cateNode.getProperty(EXO_MODERATORS).getValues());
if (cateMods != null && cateMods.length > 0 && !Utils.isEmpty(cateMods[0])) {
if (ForumServiceUtils.isModerator(cateMods, userName))
continue;
}
if (forumNode.hasProperty(EXO_MODERATORS)) {
String[] oldUserNamesModerate = PropertyReader.valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues());
List<String> list = new ArrayList<String>();
for (String string : oldUserNamesModerate) {
if (!string.equals(userName)) {
list.add(string);
}
}
forumNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list));
forumNode.setProperty(EXO_TEMP_MODERATORS, oldUserNamesModerate);
}
} else {
String[] oldUserNamesModerate = new String[] {};
if (forumNode.hasProperty(EXO_MODERATORS)) {
oldUserNamesModerate = PropertyReader.valuesToArray(forumNode.getProperty(EXO_MODERATORS).getValues());
}
List<String> list = new ArrayList<String>();
for (String string : oldUserNamesModerate) {
if (!string.equals(userName)) {
list.add(string);
}
}
list.add(userName);
forumNode.setProperty(EXO_MODERATORS, Utils.getStringsInList(list));
forumNode.setProperty(EXO_TEMP_MODERATORS, oldUserNamesModerate);
if (cateNode.hasProperty(EXO_USER_PRIVATE)) {
list = Utils.valuesToList(cateNode.getProperty(EXO_USER_PRIVATE).getValues());
if (list.size() > 0 && !Utils.isEmpty(list.get(0)) && !list.contains(userName)) {
String[] strings = new String[list.size() + 1];
int i = 0;
for (String string : list) {
strings[i] = string;
++i;
}
strings[i] = userName;
cateNode.setProperty(EXO_USER_PRIVATE, strings);
}
}
}
} catch (Exception e) {
LOG.error("Failed to save moderate of forums", e);
}
}
if (categoryHomeNode.isNew()) {
categoryHomeNode.getSession().save();
} else {
categoryHomeNode.save();
}
}
/**
* Loads only part of the forum properties
*
* @param forumNode
* @return
* @throws Exception
*/
private Forum getForumSummary(Node forumNode) throws Exception {
Forum forum = new Forum();
PropertyReader reader = new PropertyReader(forumNode);
forum.setId(forumNode.getName());
forum.setPath(forumNode.getPath());
forum.setForumName(reader.string(EXO_NAME));
forum.setDescription(reader.string(EXO_DESCRIPTION));
forum.setModerators(reader.strings(EXO_MODERATORS));
forum.setPostCount(reader.l(EXO_POST_COUNT));
forum.setTopicCount(reader.l(EXO_TOPIC_COUNT));
forum.setIsModerateTopic(reader.bool(EXO_IS_MODERATE_TOPIC));
forum.setLastTopicPath(getLastTopicPath(reader, forum));
forum.setIsClosed(reader.bool(EXO_IS_CLOSED));
forum.setIsLock(reader.bool(EXO_IS_LOCK));
return forum;
}
private String getLastTopicPath(PropertyReader reader, Forum forum) {
String lastTopic = reader.string(EXO_LAST_TOPIC_PATH, CommonUtils.EMPTY_STR);
if (!Utils.isEmpty(lastTopic)) {
lastTopic = Utils.getTopicId(lastTopic);
lastTopic = new StringBuilder(forum.getPath()).append(CommonUtils.SLASH).append(lastTopic).toString();
}
return lastTopic;
}
private Forum getForum(Node forumNode) throws Exception {
if (forumNode == null)
return null;
Forum forum = new Forum();
PropertyReader reader = new PropertyReader(forumNode);
forum.setId(forumNode.getName());
forum.setPath(forumNode.getPath());
forum.setOwner(reader.string(EXO_OWNER));
forum.setForumName(reader.string(EXO_NAME));
forum.setForumOrder(Integer.valueOf(reader.string(EXO_FORUM_ORDER)));
forum.setCreatedDate(reader.date(EXO_CREATED_DATE));
forum.setModifiedBy(reader.string(EXO_MODIFIED_BY));
forum.setModifiedDate(reader.date(EXO_MODIFIED_DATE));
forum.setLastTopicPath(getLastTopicPath(reader, forum));
forum.setDescription(reader.string(EXO_DESCRIPTION));
forum.setPostCount(reader.l(EXO_POST_COUNT));
forum.setTopicCount(reader.l(EXO_TOPIC_COUNT));
forum.setIsModerateTopic(reader.bool(EXO_IS_MODERATE_TOPIC));
forum.setIsModeratePost(reader.bool(EXO_IS_MODERATE_POST));
forum.setIsClosed(reader.bool(EXO_IS_CLOSED));
forum.setIsLock(reader.bool(EXO_IS_LOCK));
forum.setIsAutoAddEmailNotify(reader.bool(EXO_IS_AUTO_ADD_EMAIL_NOTIFY, false));
forum.setNotifyWhenAddPost(reader.strings(EXO_NOTIFY_WHEN_ADD_POST));
forum.setNotifyWhenAddTopic(reader.strings(EXO_NOTIFY_WHEN_ADD_TOPIC));
forum.setViewer(reader.strings(EXO_VIEWER));
forum.setCreateTopicRole(reader.strings(EXO_CREATE_TOPIC_ROLE));
forum.setPoster(reader.strings(EXO_POSTER));
forum.setModerators(reader.strings(EXO_MODERATORS));
forum.setBanIP(reader.list(EXO_BAN_I_PS));
if (forumNode.isNodeType(EXO_FORUM_WATCHING)) {
if (forumNode.hasProperty(EXO_EMAIL_WATCHING))
forum.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING));
}
return forum;
}
public Forum removeForum(String categoryId, String forumId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Forum forum = null;
try {
Node catNode = getCategoryHome(sProvider).getNode(categoryId);
Node forumNode = catNode.getNode(forumId);
Map<String, Long> userPostMap = getDeletePostByUser(sProvider, forumNode);
forum = getForum(forumNode);
forumNode.setProperty(EXO_TEMP_MODERATORS, forum.getModerators());
forumNode.setProperty(EXO_MODERATORS, new String[] { " " });
forumNode.save();
forumNode.remove();
catNode.setProperty(EXO_FORUM_COUNT, catNode.getProperty(EXO_FORUM_COUNT).getLong() - 1);
catNode.save();
addUpdateUserProfileJob(userPostMap);
getTotalJobWatting(sProvider, new HashSet<String>(Arrays.asList(forum.getModerators())));
} catch (Exception e) {
logDebug("Failed to remove forum: " + forumId);
return null;
}
return forum;
}
public void moveForum(List<Forum> forums, String destCategoryPath) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String oldCatePath = "";
if (!forums.isEmpty()) {
String forumPath = forums.get(0).getPath();
oldCatePath = Utils.getCategoryPath(forumPath);
} else {
return;
}
Node forumHomeNode = getForumHomeNode(sProvider);
Session session = forumHomeNode.getSession();
Node oldCatNode = (Node) session.getItem(oldCatePath);
Node newCatNode = (Node) session.getItem(destCategoryPath);
PropertyReader reader = new PropertyReader(newCatNode);
for (Forum forum : forums) {
String newForumPath = destCategoryPath + "/" + forum.getId();
//
session.getWorkspace().move(forum.getPath(), newForumPath);
//
Node forumNode = (Node) session.getItem(newForumPath);
forumNode.setProperty(EXO_PATH, newForumPath);
String[] strModerators = forum.getModerators();
forumNode.setProperty(EXO_MODERATORS, strModerators);
if (!CommonUtils.isEmpty(strModerators)) {
Set<String> listPrivate = reader.set(EXO_USER_PRIVATE, new HashSet<String>());
if (!listPrivate.isEmpty()) {
for (int i = 0; i < strModerators.length; i++) {
listPrivate.add(strModerators[i]);
}
newCatNode.setProperty(EXO_USER_PRIVATE, listPrivate.toArray(new String[listPrivate.size()]));
}
}
}
long forumCount = forums.size();
oldCatNode.setProperty(EXO_FORUM_COUNT, new PropertyReader(oldCatNode).l(EXO_FORUM_COUNT) - forumCount);
//
forumCount += reader.l(EXO_FORUM_COUNT);
newCatNode.setProperty(EXO_FORUM_COUNT, forumCount);
//
session.save();
} catch (Exception e) {
LOG.error("Failed to move forum", e);
}
}
private void setActiveTopicByForum(SessionProvider sProvider, Node forumNode, boolean isClosed) throws Exception {
NodeIterator iter = forumNode.getNodes();
Node topicNode = null;
isClosed = !isClosed;
while (iter.hasNext()) {
topicNode = iter.nextNode();
if (topicNode.isNodeType(EXO_TOPIC)) {
topicNode.setProperty(EXO_IS_ACTIVE_BY_FORUM, isClosed);
setActivePostByTopic(sProvider, topicNode, isClosed);
}
}
if (forumNode.isNew()) {
forumNode.getSession().save();
} else {
forumNode.save();
}
}
private void setActivePostByTopic(SessionProvider sProvider, Node topicNode, boolean isActiveTopic) throws Exception {
PropertyReader reader = new PropertyReader(topicNode);
if (isActiveTopic)
isActiveTopic = reader.bool(EXO_IS_APPROVED);
if (isActiveTopic)
isActiveTopic = !(reader.bool(EXO_IS_WAITING));
if (isActiveTopic)
isActiveTopic = !(reader.bool(EXO_IS_CLOSED));
if (isActiveTopic)
isActiveTopic = reader.bool(EXO_IS_ACTIVE);
Node postNode = null;
NodeIterator iter = topicNode.getNodes();
while (iter.hasNext()) {
postNode = iter.nextNode();
if (postNode.isNodeType(EXO_POST)) {
postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, isActiveTopic);
}
}
if (topicNode.isNew()) {
topicNode.getSession().save();
} else {
topicNode.save();
}
}
/**
* @deprecated use {@link #getTopics(TopicFilter, int, int)}
*/
public JCRPageList getPageTopic(String categoryId, String forumId, String strQuery, String strOrderBy) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryNode = getCategoryHome(sProvider).getNode(categoryId);
Node forumNode = categoryNode.getNode(forumId);
String forumPath = forumNode.getPath();
String pathQuery = Utils.buildTopicQuery(getForumSortSettings(), strQuery, strOrderBy, forumPath);
QueryManager qm = categoryNode.getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(pathQuery, Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true);
return pagelist;
} catch (Exception e) {
return null;
}
}
/**
* @deprecated use {@link #getTopics(TopicFilter, int, int)}
*/
public LazyPageList<Topic> getTopicList(String categoryId, String forumId, String xpathConditions, String strOrderBy, int pageSize) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryNode = getCategoryHome(sProvider).getNode(categoryId);
Node forumNode = categoryNode.getNode(forumId);
String forumPath = forumNode.getPath();
if (xpathConditions != null && xpathConditions.length() > 0 && xpathConditions.contains("topicPermission")) {
String str = buildXpath(sProvider, forumNode);
if (str.length() > 0) {
xpathConditions = StringUtils.replace(xpathConditions, "topicPermission", "(" + str + "))");
}
}
String topicQuery = Utils.buildTopicQuery(getForumSortSettings(), xpathConditions, strOrderBy, forumPath);
TopicListAccess topicListAccess = new TopicListAccess(sessionManager, topicQuery);
return new LazyPageList<Topic>(topicListAccess, pageSize);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to retrieve topic list for forum " + forumId, e);
}
return null;
}
}
//
private String buildXpath(SessionProvider sProvider, Node forumNode) throws Exception {
QueryManager qm = getCategoryHome(sProvider).getSession().getWorkspace().getQueryManager();
StringBuilder qrBuilder = new StringBuilder(JCR_ROOT);
qrBuilder.append(forumNode.getPath())
.append("/element(*,").append(EXO_TOPIC).append(")[@").append(EXO_IS_WAITING).append("='false' and @")
.append(EXO_IS_ACTIVE).append("='true' and @").append(EXO_IS_CLOSED)
.append("='false' and (not(@").append(EXO_CAN_VIEW).append(") or @").append(EXO_CAN_VIEW)
.append("='' or @").append(EXO_CAN_VIEW).append("=' ')]");
Query query = qm.createQuery(qrBuilder.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
StringBuilder builder = new StringBuilder();
boolean isOr = false;
while (iter.hasNext()) {
Node node = iter.nextNode();
if (isOr)
builder.append(" and ");
builder.append("@").append(EXO_ID).append("!='").append(node.getName()).append("'");
isOr = true;
}
return builder.toString();
}
public List<Topic> getTopics(TopicFilter filter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildTopicQuery(filter, true), offset, limit, true);
List<Topic> topicList = new ArrayList<Topic>();
if (iter != null && iter.getSize() > 0) {
while (iter.hasNext()) {
topicList.add(getTopicNode(iter.nextNode()));
}
}
return topicList;
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to retrieve topic list for forum " + filter.forumId(), e);
}
return new ArrayList<Topic>();
}
}
private String buildTopicQuery(TopicFilter filter, boolean hasOrder) throws Exception {
SortSettings sortSettings = getTopicSortSettings();
SortField orderBy = sortSettings.getField();
Direction orderType = sortSettings.getDirection();
String forumPath = new StringBuilder("/").append(dataLocator.getForumCategoriesLocation())
.append("/").append(filter.categoryId()).append("/").append(filter.forumId()).toString();
StringBuilder sqlBuilder = jcrPathLikeAndNotLike(EXO_TOPIC, forumPath);
if (filter.isAdmin() == false) {
StringBuilder strQuery = new StringBuilder();
strQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false"));
if (filter.isApproved()) {
strQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true"));
}
if (Utils.isEmpty(filter.viewers()) == true) {
// public from parent ==> user is owner or user in can view or can view is empty
strQuery.append(" AND (").append(Utils.EXO_OWNER).append("='").append(filter.userLogin()).append("' OR ")
.append(Utils.buildSQLByUserInfo(EXO_CAN_VIEW, UserHelper.getAllGroupAndMembershipOfUser(null)))
.append(" OR ").append(Utils.buildSQLHasProperty(EXO_CAN_VIEW)).append(")");
} else if (ForumServiceUtils.hasPermission(filter.viewers(), filter.userLogin()) == false) {
// has not permission from parent ==> user is owner or user in can view
strQuery.append(" AND (").append(Utils.EXO_OWNER).append("='").append(filter.userLogin()).append("' OR ")
.append(Utils.buildSQLByUserInfo(EXO_CAN_VIEW, UserHelper.getAllGroupAndMembershipOfUser(null)))
.append(")");
} else {
// has permission from parent ==> empty
}
sqlBuilder.append(strQuery);
}
if (hasOrder == true) {
sqlBuilder.append(" ORDER BY ").append(EXO_IS_STICKY).append(DESC);
String strOrderBy = filter.orderBy();
if (strOrderBy == null || Utils.isEmpty(strOrderBy)) {
if (orderBy != null) {
sqlBuilder.append(", exo:").append(orderBy.toString()).append(" ").append(orderType);
if (!orderBy.equals(SortField.LASTPOST)) {
sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC);
}
} else {
sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC);
}
} else {
sqlBuilder.append(", exo:").append(strOrderBy);
if (strOrderBy.indexOf(SortField.LASTPOST.toString()) < 0) {
sqlBuilder.append(", ").append(EXO_LAST_POST_DATE).append(DESC);
}
}
}
return sqlBuilder.toString();
}
public int getTopicsCount(TopicFilter filter) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = null;
if (Utils.isEmpty(filter.userName()) == false) {
iter = getNodeIteratorBySQLQuery(sProvider, buildQueryTopicsByUser(filter, false), 0, 0, false);
} else {
iter = getNodeIteratorBySQLQuery(sProvider, buildTopicQuery(filter, false), 0, 0, false);
}
return (int) ((iter != null) ? iter.getSize() : 0);
} catch (Exception e) {
return 0;
}
}
public List<Topic> getTopics(String categoryId, String forumId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Topic> topics = new ArrayList<Topic>();
DataStorage storage = getCachedDataStorage();
try {
Node forumNode = getCategoryHome(sProvider).getNode(categoryId).getNode(forumId);
NodeIterator iter = forumNode.getNodes();
while (iter.hasNext()) {
try {
Node topicNode = iter.nextNode();
if (topicNode.isNodeType(EXO_TOPIC)) {
topics.add(storage.getTopicByPath(topicNode.getPath(), false));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can not get topic", e);
}
}
}
} catch (Exception e) {
return null;
}
return topics;
}
public void setViewCountTopic(String path, String userRead) {
if (userRead != null && userRead.length() > 0 && !userRead.equals(UserProfile.USER_GUEST)) {
if (updatingView.containsKey(path)) {
int value = updatingView.get((path));
updatingView.put(path, value + 1);
} else {
updatingView.put(path, 1);
}
}
}
public void writeViews() {
//
Map<String, Integer> map = updatingView;
updatingView = new ConcurrentHashMap<String, Integer>();
//
SessionProvider sProvider = CommonUtils.createSystemProvider();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
try {
Node topicNode = getCategoryHome(sProvider).getNode(entry.getKey());
long newViewCount = new PropertyReader(topicNode).l(EXO_VIEW_COUNT) + entry.getValue();
topicNode.setProperty(EXO_VIEW_COUNT, newViewCount);
if (topicNode.isNew()) {
topicNode.getSession().save();
} else {
topicNode.save();
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Failed to set view number for topic with path %s", entry.getKey()), e);
}
}
}
}
public Topic getTopic(String categoryId, String forumId, String topicId, String userRead) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
String topicPath = topicId;
try {
if (!Utils.isEmpty(categoryId)) {
topicPath = new StringBuilder(categoryId).append("/").append(forumId).append("/").append(topicId).toString();
}
Node topicNode = getCategoryHome(sProvider).getNode(topicPath);
return getTopicNode(topicNode);
} catch (Exception e) {
logDebug("Getting the topic " + topicPath + " is unsuccessfully.", e);
return null;
}
}
public Topic getTopicSummary(String topicPath) {
try {
return getTopicSummary(topicPath, false);
} catch (Exception e) {
return null;
}
}
@Override
public boolean topicHasPoll(String topicPath) {
try {
return new PropertyReader(getTopicNodeByPath(topicPath, false)).bool(EXO_IS_POLL, false);
} catch (Exception e) {
return false;
}
}
public Topic getTopicSummary(String topicPath, boolean isLastPost) throws Exception {
return getTopicNodeSummary(getTopicNodeByPath(topicPath, isLastPost));
}
public Topic getTopicByPath(String topicPath, boolean isLastPost) throws Exception {
return getTopicNode(getTopicNodeByPath(topicPath, isLastPost));
}
private Node getTopicNodeByPath(String topicPath, boolean isLastPost) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node catogoryHome = getCategoryHome(sProvider);
if (topicPath == null || topicPath.length() <= 0)
return null;
if (topicPath.indexOf(catogoryHome.getName()) < 0)
topicPath = catogoryHome.getPath() + "/" + topicPath;
Node topicNode = (Node) catogoryHome.getSession().getItem(topicPath);
if (topicNode == null && isLastPost) {
String forumPath = Utils.getForumPath(topicPath);
topicNode = queryLastTopic(sProvider, forumPath);
}
return topicNode;
} catch (RepositoryException e) {
if (topicPath != null && topicPath.length() > 0 && isLastPost) {
String forumPath = Utils.getForumPath(topicPath);
return queryLastTopic(sProvider, forumPath);
}
} catch (Exception e) {
return null;
}
return null;
}
public void queryLastPostForum(String forumPath) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
queryLastTopic(sProvider, forumPath);
} finally {
sProvider.close();
}
}
private Node queryLastTopic(SessionProvider sProvider, String forumPath) throws Exception {
try {
Node forumHomeNode = getForumHomeNode(sProvider);
Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath);
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_TOPIC, forumPath);
sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true"))
.append(" ORDER BY ").append(EXO_LAST_POST_DATE).append(DESC);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false);
String lastTopicPath = StringUtils.EMPTY;
boolean isModerateTopic = new PropertyReader(forumNode).bool(EXO_IS_MODERATE_TOPIC);
Node topicNode = null;
while (iter.hasNext()) {
topicNode = iter.nextNode();
if (isModerateTopic == false || topicNode.getProperty(EXO_IS_APPROVED).getBoolean()) {
lastTopicPath = topicNode.getName();
break;
}
}
forumNode.setProperty(EXO_LAST_TOPIC_PATH, lastTopicPath);
forumNode.getSession().save();
return topicNode;
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to query last topic", e);
}
return null;
}
}
private Topic getTopicNodeSummary(Node topicNode) throws RepositoryException {
if (topicNode == null)
return null;
Topic topicNew = new Topic();
PropertyReader reader = new PropertyReader(topicNode);
topicNew.setId(topicNode.getName());
topicNew.setPath(topicNode.getPath());
topicNew.setIcon(reader.string(EXO_ICON));
topicNew.setOwner(reader.string(EXO_OWNER));
topicNew.setTopicName(reader.string(EXO_NAME));
topicNew.setLastPostBy(reader.string(EXO_LAST_POST_BY));
topicNew.setLastPostDate(reader.date(EXO_LAST_POST_DATE));
topicNew.setIsClosed(reader.bool(EXO_IS_CLOSED));
topicNew.setIsApproved(reader.bool(EXO_IS_APPROVED));
topicNew.setIsActive(reader.bool(EXO_IS_ACTIVE));
topicNew.setIsPoll(reader.bool(EXO_IS_POLL));
topicNew.setCanView(reader.strings(EXO_CAN_VIEW, new String[] {}));
return topicNew;
}
private Topic getTopicUpdate(Node topicNode, Topic topic, boolean isSummary) throws Exception {
PropertyReader reader = new PropertyReader(topicNode);
if (isSummary) {
topic.setLastPostDate(reader.date(EXO_LAST_POST_DATE));
topic.setLastPostBy(reader.string(EXO_LAST_POST_BY));
topic.setOwner(reader.string(EXO_OWNER));
topic.setTopicName(reader.string(EXO_NAME));
topic.setDescription(reader.string(EXO_DESCRIPTION));
topic.setPostCount(reader.l(EXO_POST_COUNT));
topic.setViewCount(reader.l(EXO_VIEW_COUNT));
topic.setNumberAttachment(reader.l(EXO_NUMBER_ATTACHMENTS));
topic.setIsSticky(reader.bool(EXO_IS_STICKY));
topic.setUserVoteRating(reader.strings(EXO_USER_VOTE_RATING));
topic.setVoteRating(reader.d(EXO_VOTE_RATING));
}
// some properties get again because update new data.
topic.setIsWaiting(reader.bool(EXO_IS_WAITING));
topic.setIsActive(reader.bool(EXO_IS_ACTIVE));
topic.setIsActiveByForum(reader.bool(EXO_IS_ACTIVE_BY_FORUM));
if (topicNode.getParent().getProperty(EXO_IS_LOCK).getBoolean())
topic.setIsLock(true);
else
topic.setIsLock(reader.bool(EXO_IS_LOCK));
topic.setIsClosed(reader.bool(EXO_IS_CLOSED));
// update more properties for topic.
topic.setCreatedDate(reader.date(EXO_CREATED_DATE));
topic.setModifiedBy(reader.string(EXO_MODIFIED_BY));
topic.setModifiedDate(reader.date(EXO_MODIFIED_DATE));
topic.setIsModeratePost(reader.bool(EXO_IS_MODERATE_POST));
topic.setIsNotifyWhenAddPost(reader.string(EXO_IS_NOTIFY_WHEN_ADD_POST, null));
topic.setLink(reader.string(EXO_LINK));
topic.setTagId(reader.strings(EXO_TAG_ID));
topic.setCanView(reader.strings(EXO_CAN_VIEW, new String[] {}));
topic.setCanPost(reader.strings(EXO_CAN_POST, new String[] {}));
if (topicNode.isNodeType(EXO_FORUM_WATCHING))
topic.setEmailNotification(reader.strings(EXO_EMAIL_WATCHING, new String[] {}));
try {
if (reader.l(EXO_NUMBER_ATTACHMENTS) > 0) {
String idFirstPost = topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST);
Node FirstPostNode = topicNode.getNode(idFirstPost);
topic.setAttachments(getAttachmentsByNode(FirstPostNode));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to set attachments in topic.", e);
}
}
return topic;
}
public Topic getTopicUpdate(Topic topic, boolean isSummary) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumHomeNode = getForumHomeNode(sProvider);
Node topicNode = (Node) forumHomeNode.getSession().getItem(topic.getPath());
return getTopicUpdate(topicNode, topic, isSummary);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get topic", e);
}
}
return topic;
}
public Topic getTopicNode(Node topicNode) throws Exception {
if (topicNode == null)
return null;
Topic topic = getTopicNodeSummary(topicNode);
return getTopicUpdate(topicNode, topic, true);
}
/**
* @deprecated use {@link #getTopicsByDate(long, String, int, int)}
*/
public JCRPageList getPageTopicOld(long date, String forumPatch) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String sqlQuery = buildSQLQueryGetTopicByDate(date, forumPatch);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false);
return new ForumPageList(iter, 10, sqlQuery, true);
} catch (Exception e) {
return null;
}
}
public List<Topic> getTopicsByDate(long date, String forumPath, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
List<Topic> topics = new ArrayList<Topic>();
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), offset, limit, false);
while (iter.hasNext()) {
Node node = iter.nextNode();
topics.add(getTopicNode(node));
}
return topics;
} catch (Exception e) {
return null;
}
}
private String buildSQLQueryGetTopicByDate(long date, String forumPath) throws Exception {
StringBuilder sqlBuilder = new StringBuilder("SELECT * FROM ").append(EXO_TOPIC);
sqlBuilder.append(" WHERE ").append(JCR_PATH).append(" LIKE '");
if (Utils.isEmpty(forumPath) == false) {
sqlBuilder.append(forumPath).append("/%' AND NOT ").append(JCR_PATH).append(" LIKE '").append(forumPath).append("/%/%'");
} else {
sqlBuilder.append("/").append(dataLocator.getForumCategoriesLocation()).append("/%'");
}
Calendar newDate = getGreenwichMeanTime();
newDate.setTimeInMillis(newDate.getTimeInMillis() - date * 86400000);
sqlBuilder.append(" AND (").append(EXO_LAST_POST_DATE).append(" <= TIMESTAMP '").append(ISO8601.format(newDate)).append("') ORDER BY ").append(EXO_CREATED_DATE).append(ASC);
return sqlBuilder.toString();
}
public List<Topic> getAllTopicsOld(long date, String forumPath) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Topic> topics = new ArrayList<Topic>();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), 0, 0, false);
Topic topic;
while (iter.hasNext()) {
Node node = iter.nextNode();
topic = new Topic();
topic.setId(node.getName());
topic.setPath(node.getPath());
topic.setIsActive(node.getProperty(EXO_IS_ACTIVE).getBoolean());
topic.setPostCount(node.getProperty(EXO_POST_COUNT).getLong());
topics.add(topic);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get all topic old", e);
}
}
return topics;
}
public long getTotalTopicOld(long date, String forumPath) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildSQLQueryGetTopicByDate(date, forumPath), 0, 0, false);
return iter.getSize();
} catch (Exception e) {
return 0;
}
}
/**
* @deprecated use {@link #getTopicsByUser(TopicFilter, int, int)}
*/
public JCRPageList getPageTopicByUser(String userName, boolean isMod, String strOrderBy) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
TopicFilter filter = new TopicFilter(userName, isMod, strOrderBy);
String sqlQuery = buildQueryTopicsByUser(filter, true);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false);
return new ForumPageList(iter, 10, sqlQuery, true);
} catch (Exception e) {
return null;
}
}
private String buildQueryTopicsByUser(TopicFilter filter, boolean hasOrder) {
StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_TOPIC);
sqlQuery.append(" WHERE ").append(Utils.getSQLQueryByProperty("", EXO_OWNER, filter.userName()));
if (filter.isAdmin() == false) {
sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_CLOSED, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE, "true"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE_BY_FORUM, "true"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true"));
}
if (hasOrder == true) {
sqlQuery.append(" ORDER BY ").append(EXO_IS_STICKY).append(DESC);
if (Utils.isEmpty(filter.orderBy()) == false) {
sqlQuery.append(",exo:").append(filter.orderBy());
if (EXO_CREATED_DATE.indexOf(filter.orderBy()) < 0) {
sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC);
}
} else {
sqlQuery.append(", ").append(EXO_CREATED_DATE).append(ASC);
}
}
return sqlQuery.toString();
}
public List<Topic> getTopicsByUser(TopicFilter filter, int offset, int limit) throws Exception {
// String userName, boolean isAdmin, String orderBy
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, buildQueryTopicsByUser(filter, true), offset, limit, true);
List<Topic> topics = new ArrayList<Topic>();
while (iter.hasNext()) {
Node node = iter.nextNode();
topics.add(getTopicNode(node));
}
return topics;
} catch (Exception e) {
return null;
}
}
public void modifyTopic(List<Topic> topics, int type) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumHomeNode = getForumHomeNode(sProvider);
long topicCount = 0;
long postCount = 0;
Node forumNode = null;
try {
String topicPath = topics.get(0).getPath();
forumNode = (Node) forumHomeNode.getSession().getItem(topicPath).getParent();
topicCount = forumNode.getProperty(EXO_TOPIC_COUNT).getLong();
postCount = forumNode.getProperty(EXO_POST_COUNT).getLong();
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get node by path", e);
}
}
Set<String> userIdsp = new HashSet<String>(new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>()));
for (Topic topic : topics) {
try {
String topicPath = topic.getPath();
Node topicNode = (Node) forumHomeNode.getSession().getItem(topicPath);
switch (type) {
case Utils.CLOSE: {
topicNode.setProperty(EXO_IS_CLOSED, topic.getIsClosed());
setActivePostByTopic(sProvider, topicNode, !(topic.getIsClosed()));
break;
}
case Utils.LOCK: {
topicNode.setProperty(EXO_IS_LOCK, topic.getIsLock());
break;
}
case Utils.APPROVE: {
topicNode.setProperty(EXO_IS_APPROVED, topic.getIsApproved());
addNotificationTask(topicNode.getParent().getPath(), topic, null, new MessageBuilder(), true);
setActivePostByTopic(sProvider, topicNode, topic.getIsApproved());
getTotalJobWatting(sProvider, userIdsp);
break;
}
case Utils.STICKY: {
topicNode.setProperty(EXO_IS_STICKY, topic.getIsSticky());
break;
}
case Utils.WAITING: {
boolean isWaiting = topic.getIsWaiting();
topicNode.setProperty(EXO_IS_WAITING, isWaiting);
setActivePostByTopic(sProvider, topicNode, !(isWaiting));
if (!isWaiting) {
addNotificationTask(topicNode.getParent().getPath(), topic, null, new MessageBuilder(), true);
}
getTotalJobWatting(sProvider, userIdsp);
break;
}
case Utils.ACTIVE: {
topicNode.setProperty(EXO_IS_ACTIVE, topic.getIsActive());
setActivePostByTopic(sProvider, topicNode, topic.getIsActive());
getTotalJobWatting(sProvider, userIdsp);
break;
}
case Utils.CHANGE_NAME: {
topicNode.setProperty(EXO_NAME, topic.getTopicName());
try {
Node nodeFirstPost = topicNode.getNode(topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST));
nodeFirstPost.setProperty(EXO_NAME, topic.getTopicName());
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get node by path", e);
}
}
break;
}
case Utils.VOTE_RATING: {
topicNode.setProperty(EXO_USER_VOTE_RATING, topic.getUserVoteRating());
topicNode.setProperty(EXO_VOTE_RATING, topic.getVoteRating());
break;
}
default:
break;
}
if (type == Utils.APPROVE || type == Utils.WAITING) {
if (!topic.getIsWaiting() && topic.getIsApproved()) {
topicCount = topicCount + 1;
postCount = postCount + (topicNode.getProperty(EXO_POST_COUNT).getLong() + 1);
}
}
if ((type == Utils.APPROVE || type == Utils.WAITING || type == Utils.ACTIVE || type == Utils.CLOSE) || forumNode.hasProperty(EXO_LAST_TOPIC_PATH)
|| (forumNode.getProperty(EXO_LAST_TOPIC_PATH).getString().equals(topicNode.getName()) || Utils.isEmpty(forumNode.getProperty(EXO_LAST_TOPIC_PATH).getString()))) {
//
addQueryLastPostTask(forumNode.getPath());
}
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get node by path", e);
}
}
}
if (type == Utils.APPROVE || type == Utils.WAITING) {
forumNode.setProperty(EXO_TOPIC_COUNT, topicCount);
forumNode.setProperty(EXO_POST_COUNT, postCount);
}
if (forumNode.isNew()) {
forumNode.getSession().save();
} else {
forumNode.save();
}
} catch (Exception e) {
LOG.error("Failed to modify topic.", e);
}
}
/**
* This method is call by StatisticEventListener to update user's profile when new topic is added
*
* @param owner user's name of an user that create the topic
* @throws Exception
*/
public void updateProfileAddTopic(String owner) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Node profileHomeNode = getUserProfileHome(sProvider);
if (profileHomeNode.hasNode(owner)) {
Node profileNode = profileHomeNode.getNode(owner);
long totalTopicByUser = profileNode.getProperty(EXO_TOTAL_TOPIC).getLong();
profileNode.setProperty(EXO_TOTAL_TOPIC, totalTopicByUser + 1);
} else if (Utils.isEmpty(owner) == false) {
Node newProfileNode = profileHomeNode.addNode(owner, EXO_FORUM_USER_PROFILE);
newProfileNode.setProperty(EXO_USER_ID, owner);
newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER);
if (isAdminRole(sProvider, owner)) {
newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN);
}
newProfileNode.setProperty(EXO_TOTAL_TOPIC, 1);
}
//
profileHomeNode.getSession().save();
} catch (Exception e) {
LOG.warn("Failed to update user profile when add topic", e);
} finally {
sProvider.close();
}
}
/**
* Get the owner of created post or topic by path
*
* @param path the post or topic node path
* @return user's name
*/
public String getOwner(String path) {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Node node = getNodeAt(sProvider, path);
return new PropertyReader(node).string(EXO_OWNER, "");
} catch (Exception e) {
return null;
} finally {
sProvider.close();
}
}
public void saveTopic(String categoryId, String forumId, Topic topic, boolean isNew, boolean isMove, MessageBuilder messageBuilder) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId);
Node topicNode;
boolean isChangeClose = false;
if (isNew) {
topicNode = forumNode.addNode(topic.getId(), EXO_TOPIC);
topicNode.setProperty(EXO_ID, topic.getId());
topicNode.setProperty(EXO_OWNER, topic.getOwner());
Calendar calendar = getGreenwichMeanTime();
topic.setCreatedDate(calendar.getTime());
topicNode.setProperty(EXO_CREATED_DATE, calendar);
topicNode.setProperty(EXO_LAST_POST_BY, topic.getOwner());
if (isMove && topic.getLastPostDate() != null) {
calendar.setTime(topic.getLastPostDate());
}
topicNode.setProperty(EXO_LAST_POST_DATE, calendar);
topicNode.setProperty(EXO_POST_COUNT, -1);
topicNode.setProperty(EXO_VIEW_COUNT, 0);
topicNode.setProperty(EXO_TAG_ID, topic.getTagId());
topicNode.setProperty(EXO_IS_ACTIVE_BY_FORUM, true);
topicNode.setProperty(EXO_IS_POLL, topic.getIsPoll());
topicNode.setProperty(EXO_LINK, CommonUtils.getURI(topic.getLink()));
topicNode.setProperty(EXO_PATH, forumId);
if (!forumNode.getProperty(EXO_IS_MODERATE_TOPIC).getBoolean() && !topic.getIsWaiting()) {
long newTopicCount = forumNode.getProperty(EXO_TOPIC_COUNT).getLong() + 1;
forumNode.setProperty(EXO_TOPIC_COUNT, newTopicCount);
}
} else {
topicNode = forumNode.getNode(topic.getId());
isChangeClose = (topic.getIsClosed() != topicNode.getProperty(EXO_IS_CLOSED).getBoolean());
}
topicNode.setProperty(EXO_NAME, topic.getTopicName());
topicNode.setProperty(EXO_MODIFIED_BY, topic.getModifiedBy());
topicNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime());
topicNode.setProperty(EXO_DESCRIPTION, topic.getDescription());
topicNode.setProperty(EXO_ICON, topic.getIcon());
topicNode.setProperty(EXO_IS_MODERATE_POST, topic.getIsModeratePost());
topicNode.setProperty(EXO_IS_NOTIFY_WHEN_ADD_POST, topic.getIsNotifyWhenAddPost());
topicNode.setProperty(EXO_IS_CLOSED, topic.getIsClosed());
topicNode.setProperty(EXO_IS_LOCK, topic.getIsLock());
topicNode.setProperty(EXO_IS_APPROVED, topic.getIsApproved());
topicNode.setProperty(EXO_IS_STICKY, topic.getIsSticky());
topicNode.setProperty(EXO_IS_WAITING, topic.getIsWaiting());
topicNode.setProperty(EXO_IS_ACTIVE, topic.getIsActive());
topicNode.setProperty(EXO_USER_VOTE_RATING, topic.getUserVoteRating());
topicNode.setProperty(EXO_VOTE_RATING, topic.getVoteRating());
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, topic.getNumberAttachment());
topicNode.setProperty(EXO_CAN_POST, convertArray(topic.getCanPost()));
topicNode.setProperty(EXO_CAN_VIEW, convertArray(topic.getCanView()));
topic.setPath(topicNode.getPath());
//
if (isNew) {
forumNode.getSession().save();
//
addNotificationTask(forumNode.getPath(), topic, null, messageBuilder, true);
} else {
forumNode.save();
}
//
if (topic.getIsWaiting() || !topic.getIsApproved()) {
getTotalJobWatting(sProvider, new HashSet<String>(new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>())));
}
if (isNew || isChangeClose) {
//
addQueryLastPostTask(forumNode.getPath());
}
if (!isMove) {
if (isNew) {
// createPost first
String id = topic.getId().replaceFirst(Utils.TOPIC, Utils.POST);
Post post = new Post();
post.setId(id);
post.setOwner(topic.getOwner());
post.setCreatedDate(new Date());
post.setName(topic.getTopicName());
post.setMessage(topic.getDescription());
post.setRemoteAddr("");
post.setIcon(topic.getIcon());
post.setIsApproved(true);
post.setAttachments(topic.getAttachments());
post.setUserPrivate(new String[] { EXO_USER_PRI });
post.setLink(topic.getLink());
post.setRemoteAddr(topic.getRemoteAddr());
savePost(categoryId, forumId, topic.getId(), post, true, messageBuilder);
} else {
String id = topic.getId().replaceFirst(Utils.TOPIC, Utils.POST);
if (topicNode.hasNode(id)) {
Node fistPostNode = topicNode.getNode(id);
Post post = getPost(fistPostNode);
post.setModifiedBy(topic.getModifiedBy());
post.setModifiedDate(new Date());
post.setEditReason(topic.getEditReason());
post.setName(topic.getTopicName());
post.setMessage(topic.getDescription());
post.setIcon(topic.getIcon());
post.setAttachments(topic.getAttachments());
savePost(categoryId, forumId, topic.getId(), post, false, messageBuilder);
}
}
}
} catch (Exception e) {
LOG.error("Failed to save topic", e);
if (isNew) {
topic = null;
}
}
}
private Map<String, Long> getDeletePostByUser(SessionProvider sProvider, Node node) throws Exception {
Map<String, Long> userPostMap = new HashMap<String, Long>();
StringBuilder sqlQuery = new StringBuilder();
if (node.isNodeType(EXO_TOPIC)) {
sqlQuery = jcrPathLikeAndNotLike(EXO_POST, node.getPath());
} else if (node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_FORUM_CATEGORY)) {
sqlQuery.append("SELECT * FROM ").append(EXO_POST).append(" WHERE ").append(JCR_PATH).append(" LIKE '").append(node.getPath()).append("/%'");
}
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false);
Node post = null;
String owner = null;
while (iter.hasNext()) {
post = iter.nextNode();
try {
owner = post.getProperty(EXO_OWNER).getString();
userPostMap.put(owner, (userPostMap.get(owner) != null ? userPostMap.get(owner) : 0) + 1);
} catch (Exception e) {
LOG.error("Failed to get deleted post by user.", e);
}
}
return userPostMap;
}
public void updateUserProfileInfo(String name) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node userProfileHome = getUserProfileHome(sProvider);
Node userNode = null;
Map<String, Long> userPostMap = (HashMap<String, Long>) infoMap.get(name);
for (Map.Entry<String, Long> entry : userPostMap.entrySet()) {
String user = entry.getKey();
try {
userNode = userProfileHome.getNode(user);
long totalPost = userNode.getProperty(EXO_TOTAL_POST).getLong();
userNode.setProperty(EXO_TOTAL_POST, totalPost - userPostMap.get(user));
userNode.save();
} catch (PathNotFoundException e) {
LOG.debug("UserProfile of user: " + user + " not existing.");
}
}
infoMap.remove(name);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to update user profile info", e);
}
}
}
private void addUpdateUserProfileJob(Map<String, Long> userPostMap) {
try {
Calendar cal = new GregorianCalendar();
PeriodInfo periodInfo = new PeriodInfo(cal.getTime(), null, 1, 86400000);
String name = String.valueOf(cal.getTime().getTime());
JobInfo info = new JobInfo(name, KNOWLEDGE_SUITE_FORUM_JOBS, UpdateUserProfileJob.class);
JobSchedulerService schedulerService = CommonsUtils.getService(JobSchedulerService.class);
String repoName = CommonsUtils.getRepository().getConfiguration().getName();
JobDataMap jdatamap = new JobDataMap();
jdatamap.put(Utils.CACHE_REPO_NAME, repoName);
infoMap.put(name, userPostMap);
schedulerService.addPeriodJob(info, periodInfo, jdatamap);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to add job for update user profile ", e);
}
}
}
public Topic removeTopic(String categoryId, String forumId, String topicId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumNode = getCategoryHome(sProvider).getNode(categoryId + "/" + forumId);
Topic topic = getTopic(categoryId, forumId, topicId, UserProfile.USER_GUEST);
Node topicNode = forumNode.getNode(topicId);
PropertyReader readerFor = new PropertyReader(forumNode);
Map<String, Long> userPostMap = getDeletePostByUser(sProvider, topicNode);
if (topic.getIsApproved() && !topic.getIsWaiting()) {
// update TopicCount for Forum
forumNode.setProperty(EXO_TOPIC_COUNT, readerFor.l(EXO_TOPIC_COUNT) - 1);
// update PostCount for Forum
long newPostCount = readerFor.l(EXO_POST_COUNT) - (topic.getPostCount() + 1);
forumNode.setProperty(EXO_POST_COUNT, (newPostCount > 0) ? newPostCount : 0);
}
topicNode.remove();
forumNode.save();
if (!topic.getIsActive() || !topic.getIsApproved() || topic.getIsWaiting()) {
getTotalJobWatting(sProvider, new HashSet<String>(readerFor.list(EXO_MODERATORS, new ArrayList<String>())));
}
//
addQueryLastPostTask(forumNode.getPath());
try {
calculateLastRead(sProvider, null, forumId, topicId);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to update last read topic", e);
}
}
addUpdateUserProfileJob(userPostMap);
return topic;
} catch (Exception e) {
LOG.error("Failed to remove topic", e);
return null;
}
}
private String getEmailUser(SessionProvider sProvider, String userId) throws Exception {
return new PropertyReader(getUserProfileNode(sProvider, userId)).string(EXO_EMAIL, CommonUtils.EMPTY_STR);
}
public void moveTopic(List<Topic> topics, String destForumPath, String mailContent, String link) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node forumHomeNode = getForumHomeNode(sProvider);
long tmp = 0;
String forumName = null;
Node destForumNode = (Node) forumHomeNode.getSession().getItem(destForumPath);
PropertyReader destForumReader = new PropertyReader(destForumNode);
forumName = destForumReader.string(EXO_NAME);
String owner = destForumReader.string(EXO_OWNER);
if (!Utils.isEmpty(owner) && owner.indexOf(":") > 0) {
owner = ForumServiceUtils.getUserPermission(new String[] { owner }).get(0);
}
if (Utils.isEmpty(owner)) {
owner = topics.get(0).getEditReason();
}
String categoryName = new PropertyReader(destForumNode.getParent()).string(EXO_NAME, "");
String headerSubject = new StringBuilder("[").append(categoryName).append("][").append(forumName).append("] ").toString();
MessageBuilder messageBuilder = getInfoMessageMove(sProvider, mailContent, headerSubject, true);
messageBuilder.setCatName(categoryName);
messageBuilder.setForumName(forumName);
messageBuilder.setTopicName(CommonUtils.EMPTY_STR);
messageBuilder.setOwner(CommonUtils.decodeSpecialCharToHTMLnumber(getScreenName(sProvider, owner)));
messageBuilder.setAddType(forumName);
messageBuilder.setTypes(Utils.FORUM, Utils.TOPIC, CommonUtils.EMPTY_STR, CommonUtils.EMPTY_STR);
// ----------------------- finish ----------------------
String destForumId = destForumNode.getName(), srcForumId = CommonUtils.EMPTY_STR;
for (Topic topic : topics) {
String topicPath = topic.getPath();
String newTopicPath = destForumPath + "/" + topic.getId();
// Forum remove Topic(srcForum)
Node srcForumNode = (Node) forumHomeNode.getSession().getItem(topicPath).getParent();
srcForumId = srcForumNode.getName();
// Move Topic
forumHomeNode.getSession().getWorkspace().move(topicPath, newTopicPath);
// Set TopicCount srcForum
tmp = srcForumNode.getProperty(EXO_TOPIC_COUNT).getLong();
if (tmp > 0)
tmp = tmp - 1;
else
tmp = 0;
srcForumNode.setProperty(EXO_TOPIC_COUNT, tmp);
// setPath for srcForum
addQueryLastPostTask(srcForumNode.getPath());
// Topic Move
Node topicNode = (Node) forumHomeNode.getSession().getItem(newTopicPath);
topicNode.setProperty(EXO_PATH, destForumNode.getName());
long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong() + 1;
// Forum add Topic (destForum)
destForumNode.setProperty(EXO_TOPIC_COUNT, destForumReader.l(EXO_TOPIC_COUNT) + 1);
// setPath destForum
addQueryLastPostTask(destForumNode.getPath());
// Set PostCount
tmp = srcForumNode.getProperty(EXO_POST_COUNT).getLong();
if (tmp > topicPostCount)
tmp = tmp - topicPostCount;
else
tmp = 0;
srcForumNode.setProperty(EXO_POST_COUNT, tmp);
destForumNode.setProperty(EXO_POST_COUNT, destForumReader.l(EXO_POST_COUNT) + topicPostCount);
// send email after move topic:
messageBuilder.setObjName(topic.getTopicName());
messageBuilder.setHeaderSubject(messageBuilder.getHeaderSubject() + topic.getTopicName());
messageBuilder.setLink(link.replaceFirst("pathId", topic.getId()));
Set<String> set = new HashSet<String>();
// set email author this topic
set.add(getEmailUser(sProvider, topic.getOwner()));
// set email watch this topic, forum, category parent of this topic
set.addAll(calculateMoveEmail(topicNode));
// set email watch old category, forum parent of this topic
set.addAll(calculateMoveEmail(srcForumNode));
if (!Utils.isEmpty(set.toArray(new String[set.size()]))) {
sendEmailNotification(new ArrayList<String>(set), messageBuilder.getContentEmailMoved());
}
try {
calculateLastRead(sProvider, destForumId, srcForumId, topic.getId());
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to calculate last read", e);
}
}
}
if (forumHomeNode.isNew()) {
forumHomeNode.getSession().save();
} else {
forumHomeNode.save();
}
}
private Set<String> calculateMoveEmail(Node node) throws Exception {
Set<String> set = new HashSet<String>();
while (!node.getName().equals(KSDataLocation.Locations.FORUM_CATEGORIES_HOME)) {
if (node.isNodeType(EXO_FORUM_WATCHING)) {
set.addAll(new PropertyReader(node).list(EXO_EMAIL_WATCHING, new ArrayList<String>()));
}
node = node.getParent();
}
return set;
}
private void calculateLastRead(SessionProvider sProvider, String destForumId, String srcForumId, String topicId) throws Exception {
Node profileHome = getUserProfileHome(sProvider);
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_FORUM_USER_PROFILE, profileHome.getPath());
sqlQuery.append(" AND ").append(EXO_LAST_READ_POST_OF_FORUM).append(" LIKE '%").append(topicId).append("%'");
// sqlQuery.append("AND (CONTAINS (").append(EXO_LAST_READ_POST_OF_FORUM).append(", '").append(topicId).append("'))");
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false);
List<String> list;
List<String> list2;
while (iter.hasNext()) {
list = new ArrayList<String>();
list2 = new ArrayList<String>();
Node profileNode = iter.nextNode();
PropertyReader reader = new PropertyReader(profileNode);
list = reader.list(EXO_LAST_READ_POST_OF_FORUM, new ArrayList<String>());
list2 = new ArrayList<String>(list);
boolean isRead = false;
for (String string : list) {
if (destForumId != null && string.indexOf(destForumId) >= 0) { // this forum is read, can check last access topic of forum and topic
isRead = true;
try {
long lastAccessTopicTime = 0;
long lastAccessForumTime = 0;
// check last read of src topic
List<String> readTopics = reader.list(EXO_READ_TOPIC, new ArrayList<String>());
for (String tpId : readTopics) {// for only run one.
String[] info = tpId.split(CommonUtils.COLON);
if (tpId.indexOf(topicId) >= 0 && info.length > 1) {
lastAccessTopicTime = Long.parseLong(info[1]);
if (lastAccessTopicTime > 0) {// check last read dest forum
List<String> values = reader.list(EXO_READ_FORUM, new ArrayList<String>());
for (String str : values) {// for only run one.
if (str.indexOf(destForumId) >= 0) {
if (str.indexOf(CommonUtils.COLON) > 0) {
lastAccessForumTime = Long.parseLong(str.split(CommonUtils.COLON)[1]);
break;
}
}
}
}
if (lastAccessTopicTime > lastAccessForumTime) {
list2.remove(string);
list2.add(destForumId + CommonUtils.COMMA + info[0] + CommonUtils.SLASH + info[1]); // replace topic,postId
}
break;
}
}
} catch (Exception e) {
LOG.warn("Can not calculate last read of user: " + profileNode.getName());
}
}
if (string.indexOf(srcForumId) >= 0) {// remove last read src forum if last read this forum is this topic.
list2.remove(string);
}
}
if (!isRead && destForumId != null) {
list2.add(destForumId + CommonUtils.COMMA + topicId + CommonUtils.SLASH + topicId.replace(Utils.TOPIC, Utils.POST));
}
profileNode.setProperty(EXO_LAST_READ_POST_OF_FORUM, list2.toArray(new String[list2.size()]));
}
profileHome.save();
}
public long getLastReadIndex(String path, String isApproved, String isHidden, String userLogin) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node catNode = getCategoryHome(sProvider);
Node postNode = catNode.getNode(path);
if (postNode != null) {
String topicPath = postNode.getParent().getPath();
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_POST, topicPath);
String query = Utils.getSQLQuery(isApproved, isHidden, isHidden, userLogin).toString();
if (query.isEmpty() == false) {
sqlQuery.append(" AND (").append(query).append(")");
}
Calendar cal = postNode.getProperty(EXO_CREATED_DATE).getDate();
sqlQuery.append(" AND (").append(EXO_CREATED_DATE).append(" <= TIMESTAMP '").append(ISO8601.format(cal)).append("')");
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery.toString(), 0, 0, false);
long size = iter.getSize();
boolean isView = false;
while (iter.hasNext()) {
if (iter.nextNode().getName().equals(postNode.getName())) {
isView = true;
break;
}
}
// if user can not view post open, return page 1.
if (isView == false) {
size = 1;
}
return size;
}
} catch (Exception e) {
LOG.error("Exception occurs when getting last read index", e);
}
return 0;
}
/**
* @deprecated use {@link #getPostsSplitTopic(PostFilter, int, int)}
*/
public JCRPageList getPostForSplitTopic(String topicPath) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
PostFilter filter = new PostFilter(topicPath);
String sqlQuery = makePostsSplitSQLQuery(filter, true);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false);
return new ForumPageList(iter, 10, sqlQuery.toString(), true);
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get post for split topic.", e);
}
}
return null;
}
private String makePostsSplitSQLQuery(PostFilter filter, boolean hasOrder) throws Exception {
StringBuilder topicPath = new StringBuilder();
if (filter.getTopicPath().indexOf(dataLocator.getForumCategoriesLocation()) > 0) {
topicPath.append(filter.getTopicPath());
} else {
topicPath.append("/").append(dataLocator.getForumCategoriesLocation()).append("/").append(filter.getTopicPath());
}
StringBuilder sqlQuery = jcrPathLikeAndNotLike(EXO_POST, topicPath.toString());
sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_USER_PRIVATE, EXO_USER_PRI))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_FIRST_POST, "false"));
if (hasOrder) {
sqlQuery.append(" ORDER BY ").append(EXO_CREATED_DATE).append(" ASC");
}
return sqlQuery.toString();
}
public List<Post> getPostsSplitTopic(PostFilter filter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String sqlQuery = makePostsSplitSQLQuery(filter, true);
//
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, 0, 0, false);
return getPosts(iter);
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get post for split topic.", e);
}
}
return null;
}
/**
* @deprecated use {@link #getPosts(PostFilter, int, int)}
*/
public JCRPageList getPosts(String categoryId, String forumId, String topicId, String isApproved, String isHidden, String strQuery, String userLogin) throws Exception {
try {
String isWaiting = strQuery.equals("true") || strQuery.equals("false") ? strQuery : "";
PostFilter filter = new PostFilter(categoryId, forumId, topicId, isApproved, isHidden, isWaiting, userLogin);
if (!Utils.isEmpty(strQuery)) {
LOG.warn("This method doesn't support to add more query.");
}
return new ForumPageList(null, 10, makePostsSQLQuery(filter, true), true);
} catch (PathNotFoundException e) {
return null;
}
}
private String makePostsSQLQuery(PostFilter filter, boolean hasOrder) throws Exception {
String topicPath = filter.getTopicPath();
if (Utils.isEmpty(topicPath)) {
topicPath = new StringBuffer("/").append(dataLocator.getForumCategoriesLocation()).append("/").append(filter.getCategoryId())
.append("/").append(filter.getForumId()).append("/").append(filter.getTopicId()).toString();
}
StringBuilder strBuilder = jcrPathLikeAndNotLike(EXO_POST, topicPath);
String sqlQuery = Utils.getSQLQuery(filter.getIsApproved(), filter.getIsHidden(), filter.getIsWaiting(), filter.getUserLogin()).toString();
if (sqlQuery.isEmpty() == false) {
strBuilder.append(" AND (").append(sqlQuery).append(")");
}
if (hasOrder) {
strBuilder.append(" ORDER BY ").append(EXO_CREATED_DATE).append(ASC);
}
return strBuilder.toString();
}
@Override
public List<Post> getPosts(PostFilter filter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, makePostsSQLQuery(filter, true), offset, limit, false);
return getPosts(iter);
} catch (Exception e) {
logDebug("Failed to get posts by filter of topic " + filter.getTopicId(), e);
return new ArrayList<Post>();
}
}
private List<Post> getPosts(NodeIterator iter) throws Exception {
Node currentNode = null;
List<Post> posts = new ArrayList<Post>((int) iter.getSize());
//
DataStorage dataStorage = getCachedDataStorage();
boolean hasCache = (dataStorage instanceof CachedDataStorage);
while (iter.hasNext()) {
currentNode = iter.nextNode();
if (hasCache) {
String path = currentNode.getPath();
CachedDataStorage storage = (CachedDataStorage) dataStorage;
String categoryId = Utils.getCategoryId(path), forumId = Utils.getForumId(path), topicId = Utils.getTopicId(path);
Post post = storage.getPostFromCache(categoryId, forumId, topicId, currentNode.getName());
if (post == null) {
post = getPost(currentNode);
storage.putPost(post);
}
posts.add(post);
} else {
posts.add(getPost(currentNode));
}
}
return posts;
}
public int getPostsCount(PostFilter filter) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
if (filter.isSplit()) {
return (int) getNodeIteratorBySQLQuery(sProvider, makePostsSplitSQLQuery(filter, false), 0, 0, false).getSize();
} else if (Utils.isEmpty(filter.userName()) == false) {
return (int) getNodeIteratorBySQLQuery(sProvider, queryPostsByUser(filter, false), 0, 0, false).getSize();
} else if (Utils.isEmpty(filter.getIP()) == false) {
return (int) getNodeIteratorBySQLQuery(sProvider, queryPostsByIP(filter, false), 0, 0, false).getSize();
}
//
return (int) getNodeIteratorBySQLQuery(sProvider, makePostsSQLQuery(filter, false), 0, 0, false).getSize();
} catch (Exception e) {
return 0;
}
}
public long getAvailablePost(String categoryId, String forumId, String topicId, String isApproved, String isHidden, String userLogin) throws Exception {
PostFilter filter = new PostFilter(categoryId, forumId, topicId, isApproved, isHidden, isHidden, userLogin);
return getPostsCount(filter);
}
public JCRPageList getPagePostByUser(String userName, String userId, boolean isMod, String strOrderBy) throws Exception {
if (Utils.isEmpty(userName)) {
throw new NullPointerException("userName");
}
if (Utils.isEmpty(userId)) {
throw new NullPointerException("userLogin");
}
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String query = queryPostsByUser(new PostFilter(userName, userId, isMod, strOrderBy), true);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, query, 0, 0, false);
return new ForumPageList(iter, 10, query, true);
} catch (Exception e) {
return null;
}
}
private String queryPostsByUser(PostFilter filter, boolean hasOrder) {
StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_POST);
sqlQuery.append(" WHERE ")
.append(Utils.getSQLQueryByProperty("", EXO_IS_FIRST_POST, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_OWNER, filter.userName()));
if (filter.isAdmin() == false) {
sqlQuery.append(Utils.getSQLQueryByProperty("AND", EXO_IS_APPROVED, "true"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_HIDDEN, "false"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_ACTIVE_BY_TOPIC, "true"))
.append(Utils.getSQLQueryByProperty("AND", EXO_IS_WAITING, "false"));
}
sqlQuery.append(" AND (")
.append(Utils.getSQLQueryByProperty("", EXO_USER_PRIVATE, filter.getUserLogin()))
.append(Utils.getSQLQueryByProperty("OR", EXO_USER_PRIVATE, EXO_USER_PRI))
.append(")");
if (hasOrder) {
sqlQuery.append(" ORDER BY ");
if (!Utils.isEmpty(filter.orderBy())) {
sqlQuery.append(filter.orderBy());
if (filter.orderBy().indexOf(EXO_CREATED_DATE) < 0) {
sqlQuery.append(", ").append(EXO_CREATED_DATE).append(DESC);
}
} else {
sqlQuery.append(EXO_CREATED_DATE).append(DESC);
}
}
return sqlQuery.toString();
}
public List<Post> getPostsByUser(PostFilter filter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String sqlQuery = queryPostsByUser(filter, true);
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, sqlQuery, offset, limit, false);
return getPosts(iter);
} catch (Exception e) {
return null;
}
}
public Post getPost(String categoryId, String forumId, String topicId, String postId) throws Exception {
if (StringUtils.isEmpty(postId)) {
return null;
}
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
Node postNode;
if (postId.lastIndexOf("/") > 0 || StringUtils.isEmpty(categoryId) || StringUtils.isEmpty(forumId) || StringUtils.isEmpty(topicId)) {
if (postId.indexOf(categoryHome.getName()) < 0)
postId = categoryHome.getPath() + "/" + postId;
postNode = (Node) categoryHome.getSession().getItem(postId);
} else {
postNode = categoryHome.getNode(categoryId + "/" + forumId + "/" + topicId + "/" + postId);
}
return getPost(postNode);
} catch (PathNotFoundException e) {
return null;
}
}
public JCRPageList getListPostsByIP(String ip, String strOrderBy) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String pathQuery = queryPostsByIP(new PostFilter(ip, strOrderBy), true);
//
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, pathQuery, 0, 0, false);
return new ForumPageList(iter, 5, pathQuery, true);
} catch (Exception e) {
return null;
}
}
private String queryPostsByIP(PostFilter filter, boolean hasOrder) {
StringBuilder sqlQuery = new StringBuilder("SELECT ").append(EXO_REMOTE_ADDR).append(" FROM ").append(EXO_POST);
sqlQuery.append(" WHERE ").append(Utils.getSQLQueryByProperty("", EXO_REMOTE_ADDR, filter.getIP()));
if (hasOrder) {
if (Utils.isEmpty(filter.orderBy())) {
sqlQuery.append(" ORDER BY ").append(EXO_LAST_POST_DATE).append(DESC);
} else {
sqlQuery.append(" ORDER BY exo:").append(filter.orderBy());
if (EXO_LAST_POST_DATE.indexOf(filter.orderBy()) < 0) {
sqlQuery.append(", ").append(EXO_LAST_POST_DATE).append(DESC);
}
}
}
return sqlQuery.toString();
}
public List<Post> getPostsByIP(PostFilter filter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
NodeIterator iter = getNodeIteratorBySQLQuery(sProvider, queryPostsByIP(filter, true), offset, limit, false);
List<Post> posts = new ArrayList<Post>((int) iter.getSize());
Node currentNode;
while (iter.hasNext()) {
currentNode = iter.nextNode();
posts.add(getPost(currentNode));
}
return posts;
} catch (Exception e) {
return null;
}
}
public Post getPost(Node postNode) throws Exception {
Post postNew = new Post();
PropertyReader reader = new PropertyReader(postNode);
postNew.setId(postNode.getName());
postNew.setPath(postNode.getPath());
postNew.setOwner(reader.string(EXO_OWNER));
postNew.setCreatedDate(reader.date(EXO_CREATED_DATE));
postNew.setModifiedBy(reader.string(EXO_MODIFIED_BY));
postNew.setModifiedDate(reader.date(EXO_MODIFIED_DATE));
postNew.setEditReason(reader.string(EXO_EDIT_REASON));
postNew.setName(reader.string(EXO_NAME));
postNew.setMessage(reader.string(EXO_MESSAGE));
postNew.setRemoteAddr(reader.string(EXO_REMOTE_ADDR));
postNew.setIcon(reader.string(EXO_ICON));
postNew.setLink(reader.string(EXO_LINK));
postNew.setIsApproved(reader.bool(EXO_IS_APPROVED));
postNew.setIsHidden(reader.bool(EXO_IS_HIDDEN));
postNew.setIsWaiting(reader.bool(EXO_IS_WAITING));
postNew.setFirstPost(reader.bool(EXO_IS_FIRST_POST));
postNew.setIsActiveByTopic(reader.bool(EXO_IS_ACTIVE_BY_TOPIC));
postNew.setUserPrivate(reader.strings(EXO_USER_PRIVATE));
postNew.setNumberAttach(reader.l(EXO_NUMBER_ATTACH));
if (postNew.getNumberAttach() > 0) {
postNew.setAttachments(getAttachmentsByNode(postNode));
}
return postNew;
}
private static ForumAttachment getAttachment(Node nodeContent) throws Exception {
try {
if (nodeContent.isNodeType(EXO_FORUM_ATTACHMENT) || nodeContent.isNodeType(NT_FILE)) {
BufferAttachment attachment = new BufferAttachment();
PropertyReader readerContent = new PropertyReader(nodeContent.getNode(JCR_CONTENT));
attachment.setId(nodeContent.getName());
attachment.setPathNode(nodeContent.getPath());
attachment.setMimeType(readerContent.string(JCR_MIME_TYPE, CommonUtils.EMPTY_STR));
attachment.setSize(readerContent.stream(JCR_DATA).available());
String workspace = nodeContent.getSession().getWorkspace().getName();
attachment.setWorkspace(workspace);
attachment.setPath(CommonUtils.SLASH + workspace + nodeContent.getPath());
String fileName = readerContent.string(EXO_FILE_NAME);
if (CommonUtils.isEmpty(fileName)) {
String type = attachment.getMimeType();
if (type.indexOf(CommonUtils.SLASH) > 0) {
type = type.substring(type.indexOf(CommonUtils.SLASH) + 1);
}
fileName = "avatar." + type;
}
attachment.setName(fileName);
return attachment;
}
} catch (Exception e) {
logDebug("Failed to get attachment in node: " + nodeContent.getName());
}
return null;
}
public static List<ForumAttachment> getAttachmentsByNode(Node node) throws Exception {
List<ForumAttachment> attachments = new ArrayList<ForumAttachment>();
NodeIterator postAttachments = node.getNodes();
while (postAttachments.hasNext()) {
Node nodeAttatch = postAttachments.nextNode();
ForumAttachment attachment = getAttachment(nodeAttatch);
if (attachment != null) {
attachments.add(attachment);
}
}
return attachments;
}
/**
* This method is call by StatisticEventListener to update user's profile when new post is added
*
* @param owner user's name of an user that create the post
* @param postPath node's path of the last post
*/
public void updateProfileAddPost(String owner, String postPath) {
ReentrantLock lock = this.lock;
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
lock.lock();
Node profileHomeNode = getUserProfileHome(sProvider);
Calendar lastPost = getGreenwichMeanTime();
Node postNode = (Node) profileHomeNode.getSession().getItem(postPath);
PropertyReader reader = new PropertyReader(postNode);
lastPost.setTime(reader.date(EXO_CREATED_DATE, lastPost.getTime()));
//
if (profileHomeNode.hasNode(owner)) {
Node profileNode = profileHomeNode.getNode(owner);
long totalPostByUser = 0;
totalPostByUser = profileNode.getProperty(EXO_TOTAL_POST).getLong();
profileNode.setProperty(EXO_TOTAL_POST, totalPostByUser + 1);
profileNode.setProperty(EXO_LAST_POST_DATE, lastPost);
} else if (Utils.isEmpty(owner) == false) {
Node profileNode = profileHomeNode.addNode(owner, EXO_FORUM_USER_PROFILE);
profileNode.setProperty(EXO_USER_ID, owner);
profileNode.setProperty(EXO_USER_TITLE, Utils.USER);
if (isAdminRole(sProvider, owner)) {
profileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN);
}
profileNode.setProperty(EXO_TOTAL_POST, 1);
profileNode.setProperty(EXO_LAST_POST_DATE, lastPost);
}
profileHomeNode.getSession().save();
} catch (Exception e) {
LOG.warn("Failed to save user profile of user: " + owner, e);
} finally {
lock.unlock();
sProvider.close();
}
}
private void postSaveProperties(Node postNode, Post post) throws Exception {
if (post.getModifiedBy() != null && post.getModifiedBy().length() > 0) {
postNode.setProperty(EXO_MODIFIED_BY, post.getModifiedBy());
postNode.setProperty(EXO_MODIFIED_DATE, getGreenwichMeanTime());
postNode.setProperty(EXO_EDIT_REASON, post.getEditReason());
}
postNode.setProperty(EXO_NAME, post.getName());
postNode.setProperty(EXO_MESSAGE, post.getMessage());
postNode.setProperty(EXO_REMOTE_ADDR, post.getRemoteAddr());
postNode.setProperty(EXO_ICON, post.getIcon());
postNode.setProperty(EXO_IS_APPROVED, post.getIsApproved());
postNode.setProperty(EXO_IS_HIDDEN, post.getIsHidden());
postNode.setProperty(EXO_IS_WAITING, post.getIsWaiting());
postNode.setProperty(EXO_NUMBER_ATTACH, post.getNumberAttach());
postNode.setProperty(EXO_USER_PRIVATE, post.getUserPrivate());
}
private List<String> postAttachment(Node postNode, Post post) {
List<String> listFileName = new ArrayList<String>();
List<ForumAttachment> attachments = post.getAttachments();
if (attachments != null) {
Iterator<ForumAttachment> it = attachments.iterator();
for (ForumAttachment attachment : attachments) {
BufferAttachment file = null;
listFileName.add(attachment.getId());
try {
file = (BufferAttachment) it.next();
Node nodeFile = null;
if (!postNode.hasNode(file.getId()))
nodeFile = postNode.addNode(file.getId(), EXO_FORUM_ATTACHMENT);
else
nodeFile = postNode.getNode(file.getId());
// Fix permission node
ForumServiceUtils.reparePermissions(nodeFile, "any");
Node nodeContent = null;
if (!nodeFile.hasNode(JCR_CONTENT)) {
nodeContent = nodeFile.addNode(JCR_CONTENT, EXO_FORUM_RESOURCE);
nodeContent.setProperty(JCR_MIME_TYPE, file.getMimeType());
nodeContent.setProperty(JCR_DATA, file.getInputStream());
nodeContent.setProperty(JCR_LAST_MODIFIED, getGreenwichMeanTime().getTimeInMillis());
nodeContent.setProperty(EXO_FILE_NAME, file.getName());
}
} catch (Exception e) {
LOG.error("Failed to save attachment", e);
}
}
}
return listFileName;
}
public void savePost(String categoryId, String forumId, String topicId, Post post, boolean isNew, MessageBuilder messageBuilder) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryNode = getCategoryHome(sProvider).getNode(categoryId);
Node forumNode = categoryNode.getNode(forumId);
Node topicNode = forumNode.getNode(topicId);
Node postNode;
if (isNew) {
postNode = addPost(sProvider, categoryNode, forumNode, topicNode, post);
} else {
postNode = updatePost(sProvider, topicNode, post);
}
//
try {
forumNode.getSession().save();
} catch (InvalidItemStateException e) {
LOG.warn("Probably was save post by another session");
post = null;
return;
}
if (isNew) {
addQueryLastPostTask(forumNode.getPath());
}
//
post.setPath(postNode.getPath());
//
boolean sendAlertJob = (!messageBuilder.getLink().equals("link") && (post.getUserPrivate().length == 1) &&
(!post.getIsApproved() || post.getIsHidden() || post.getIsWaiting()));
if (topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId()) == false && isNew) {
addNotificationTask(topicNode.getPath(), null, post, messageBuilder, !sendAlertJob);
}
//
if (sendAlertJob) {
getTotalJobWatting(sProvider, new HashSet<String>(new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>())));
}
// send notification message to user's private post.
if (post != null && post.getUserPrivate().length > 1) {
ForumPrivateMessage message = new ForumPrivateMessage();
message.setFrom(post.getOwner());
message.setSendTo(String.join(",",post.getUserPrivate()));
message.setType("PrivatePost");
message.setName(post.getName());
message.setMessage(post.getMessage());
message.setId(topicId + "/" + post.getId());
sendNotificationMessage(message);
}
} catch (Exception e) {
LOG.error("Failed to save post " + post.getName(), e);
post = null;
}
}
private Node addPost(SessionProvider sProvider, Node categoryNode, Node forumNode, Node topicNode, Post post) throws Exception {
Node postNode = topicNode.addNode(post.getId(), EXO_POST);
Calendar calendar = getGreenwichMeanTime();
postNode.setProperty(EXO_ID, post.getId());
postNode.setProperty(EXO_PATH, forumNode.getName());
postNode.setProperty(EXO_OWNER, post.getOwner());
post.setCreatedDate(calendar.getTime());
postNode.setProperty(EXO_CREATED_DATE, calendar);
postNode.setProperty(EXO_USER_PRIVATE, post.getUserPrivate());
postNode.setProperty(EXO_LINK, CommonUtils.getURI(post.getLink()));
boolean isFistPost = topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId());
postNode.setProperty(EXO_IS_FIRST_POST, isFistPost);
//
postSaveProperties(postNode, post);
//
postAttachment(postNode, post);
return postNode;
}
/**
* Update the number of post and also the information about the last post of topic when a new post is added
*
* @param postPath the jcr's path of the new post
* @param owner the owner of the new post
* @throws Exception
*/
public void updatePostCount(String postPath, String owner) throws Exception {
final ReentrantLock localLock = lock;
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
localLock.lock();
Session session = sessionManager.getSession(sProvider);
Node postNode = (Node) session.getItem(postPath);
Node topicNode = postNode.getParent();
Node forumNode = topicNode.getParent();
//
boolean isFirstPost = topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(postNode.getName());
PropertyReader postRead = new PropertyReader(postNode);
PropertyReader topicRead = new PropertyReader(topicNode);
PropertyReader forumRead = new PropertyReader(forumNode);
//
long topicPostCount = topicRead.l(EXO_POST_COUNT) + 1;
long newNumberAttach = topicRead.l(EXO_NUMBER_ATTACHMENTS) + postRead.l(EXO_NUMBER_ATTACH);
boolean topicActive = (!topicRead.bool(EXO_IS_CLOSED) && !topicRead.bool(EXO_IS_WAITING) &&
topicRead.bool(EXO_IS_APPROVED) && topicRead.bool(EXO_IS_ACTIVE) &&
topicRead.bool(EXO_IS_ACTIVE_BY_FORUM));
boolean postActive = (postRead.bool(EXO_IS_APPROVED) && postRead.bool(EXO_IS_HIDDEN) == false &&
postRead.bool(EXO_IS_WAITING) == false && postRead.list(EXO_USER_PRIVATE).size() != 2);
// set active by topic
postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, (topicActive || isFirstPost));
// update forum
if ((isFirstPost && !forumRead.bool(EXO_IS_MODERATE_TOPIC)) || (!isFirstPost && topicActive)) {
long forumPostCount = forumRead.l(EXO_POST_COUNT) + 1;
forumNode.setProperty(EXO_POST_COUNT, Math.max(forumPostCount, 1));
}
// update topic
if (postActive) {
topicNode.setProperty(EXO_POST_COUNT, Math.max(topicPostCount, 0));
topicNode.setProperty(EXO_LAST_POST_DATE, getGreenwichMeanTime());
topicNode.setProperty(EXO_LAST_POST_BY, owner);
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach);
}
//
session.save();
} catch (Exception e) {
LOG.warn("Failed to update forum post count when save post");
} finally {
sProvider.close();
localLock.unlock();
}
}
private Node updatePost(SessionProvider sProvider, Node topicNode, Post post) throws Exception {
Node postNode = topicNode.getNode(post.getId());
long oldNumberAttachments = postNode.getProperty(EXO_NUMBER_ATTACH).getLong();
//
postSaveProperties(postNode, post);
//
List<String> listFileName = postAttachment(postNode, post);
// remove old attachments
NodeIterator postAttachments = postNode.getNodes();
Node postAttachmentNode = null;
while (postAttachments.hasNext()) {
postAttachmentNode = postAttachments.nextNode();
if (listFileName.contains(postAttachmentNode.getName())) {
continue;
}
postAttachmentNode.remove();
}
long temp = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong() - oldNumberAttachments;
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, (temp + post.getNumberAttach()));
//
return postNode;
}
private boolean hasProperty(Node node, String property) throws Exception {
String[] strs = new PropertyReader(node).strings(property, new String[] {});
return strs.length > 0;
}
private void addNotificationTask(String nodePath, Topic topic, Post post, MessageBuilder messageBuilder, boolean isApprovePost) throws Exception {
SendNotificationTaskManager sendNotificationManager = getSendNotificationTaskManager();
if (sendNotificationManager != null) {
sendNotificationManager.addTask(new SendNotificationTask(nodePath, topic, post, messageBuilder, isApprovePost));
}
}
/**
* Check if a specific User have the permission to receive the email notification
*
* @param topicNode the underlying watched topic
* @param user the user watching the topic
* @param postAuthor the owner of the new post
* @throws Exception
*/
private boolean canReceiveNotification(Node topicNode, String user, String postAuthor) throws Exception {
//if the watching user is the one who replied to the topic then don't send notification
if(user==null || user.equals(postAuthor)){
return false;
}
Node forumNode = topicNode.getParent();
PropertyReader reader = new PropertyReader(forumNode);
// viewer of topic
Set<String> viewers = new PropertyReader(topicNode).set(EXO_CAN_VIEW, new HashSet<String>());
// viewer of forum
viewers.addAll(reader.set(EXO_VIEWER, new HashSet<String>()));
// forum of space - only check permission on forum
String[] moderators = reader.strings(EXO_MODERATE_FORUMS, new String[] {});
if (forumNode.getParent().getName().equals(Utils.CATEGORY_SPACE_ID_PREFIX)) {
// moderators
if (!CommonUtils.isEmpty(moderators) && ForumServiceUtils.hasPermission(moderators, user)) {
return true;
}
} else {
// administrators or moderators
if (isAdminRole(user) || (!CommonUtils.isEmpty(moderators) && ForumServiceUtils.hasPermission(moderators, user))) {
return true;
}
// private categories
String[] userPrivates = new PropertyReader(forumNode.getParent()).strings(EXO_USER_PRIVATE, new String[] {});
if (!ForumServiceUtils.hasPermission(userPrivates, user)) {
return false;
}
// all viewers on category
viewers.addAll(new PropertyReader(forumNode.getParent()).list(EXO_VIEWER, new ArrayList<String>()));
}
return ForumServiceUtils.hasPermission(viewers.toArray(new String[viewers.size()]), user);
}
private void sendNotificationWhenCreateTopic(SessionProvider sProvider, Node forumNode, Topic topic, MessageBuilder messageBuilder) throws Exception {
messageBuilder.setForumName(forumNode.getProperty(EXO_NAME).getString());
Node categoryNode = forumNode.getParent();
messageBuilder.setCatName(categoryNode.getProperty(EXO_NAME).getString());
messageBuilder.setTopicName(topic.getTopicName());
//
List<String> emailList = new ArrayList<String>();
List<String> emailListCate = new ArrayList<String>();
Node node = categoryNode;
Node topicNode = forumNode.getNode(topic.getId());
while (true) {
emailListCate.addAll(emailList);
emailList = new ArrayList<String>();
if (node.isNodeType(EXO_FORUM_WATCHING) && topic.getIsActive() && topic.getIsApproved() && topic.getIsActiveByForum() && !topic.getIsClosed() && !topic.getIsLock() && !topic.getIsWaiting()) {
PropertyReader reader = new PropertyReader(node);
List<String> users = reader.list(EXO_USER_WATCHING, new ArrayList<String>());
if (!users.isEmpty()) {
int i = 0;
String[] emails = reader.strings(EXO_EMAIL_WATCHING, new String[] {});
for (String user : users) {
if (user.equals(topic.getOwner()) || canReceiveNotification(topicNode, user, null)) {
emailList.add(emails[i]);
}
i++;
}
}
emailList.addAll(reader.list(EXO_NOTIFY_WHEN_ADD_TOPIC, new ArrayList<String>()));
}
//
emailList.removeAll(emailListCate);
if (emailList.size() > 0) {
String owner = getScreenName(sProvider, topic.getOwner());
messageBuilder.setObjName(node.getProperty(EXO_NAME).getString());
if (node.isNodeType(EXO_FORUM)) {
messageBuilder.setWatchType(Utils.FORUM);
} else {
messageBuilder.setWatchType(Utils.CATEGORY);
}
messageBuilder.setId(topic.getId().replaceFirst(Utils.TOPIC, Utils.POST));
messageBuilder.setAddType(Utils.TOPIC);
messageBuilder.setAddName(topic.getTopicName());
messageBuilder.setMessage(topic.getDescription());
messageBuilder.setCreatedDate(topic.getCreatedDate());
messageBuilder.setOwner(CommonUtils.decodeSpecialCharToHTMLnumber(owner));
if(Utils.isEmpty(messageBuilder.getLink())) {
messageBuilder.setLink(topic.getLink());
}
sendEmailNotification(emailList, messageBuilder.getContentEmail());
}
if(node.isNodeType(EXO_FORUM)) {
break;
}
node = forumNode;
}
}
private void sendNotificationWhenCreatePost(SessionProvider sProvider, Node topicNode, Post post, MessageBuilder messageBuilder, boolean isApprovePost) throws Exception {
if (!topicNode.getName().replaceFirst(Utils.TOPIC, Utils.POST).equals(post.getId())) {
Node userProfileHome = getUserProfileHome(sProvider);
Node forumNode = topicNode.getParent();
Node categoryNode = forumNode.getParent();
messageBuilder.setCatName(categoryNode.getProperty(EXO_NAME).getString());
messageBuilder.setForumName(forumNode.getProperty(EXO_NAME).getString());
messageBuilder.setTopicName(topicNode.getProperty(EXO_NAME).getString());
/*
* check is approved, is activate by topic and is not hidden before send mail
*/
if (post.getIsApproved() && post.getIsActiveByTopic() && !post.getIsHidden() && !post.getIsWaiting()) {
List<String> userPrivates = new ArrayList<String>();
if (!CommonUtils.isEmpty(post.getUserPrivate()) && post.getUserPrivate().length > 1) {
userPrivates.addAll(Arrays.asList(post.getUserPrivate()));
}
PropertyReader catReader = new PropertyReader(categoryNode);
PropertyReader forumReader = new PropertyReader(forumNode);
PropertyReader topicReader = new PropertyReader(topicNode);
// get all emails watched
List<String> emailListCategory = catReader.list(EXO_EMAIL_WATCHING, new ArrayList<String>());
List<String> emailListForum = forumReader.list(EXO_EMAIL_WATCHING, new ArrayList<String>());
List<String> emailListTopic = topicReader.list(EXO_EMAIL_WATCHING, new ArrayList<String>());
//
List<String> userListCategory = catReader.list(EXO_USER_WATCHING, new ArrayList<String>());
List<String> userListForum = forumReader.list(EXO_USER_WATCHING, new ArrayList<String>());
List<String> userListTopic = topicReader.list(EXO_USER_WATCHING, new ArrayList<String>());
// validate permission and remove duplicate email
// Watched on category
int i = 0;
List<String> removeEmail = new ArrayList<String>();
for (String user : userListCategory) {
if(!canReceiveNotification(topicNode, user, post.getOwner())) {
removeEmail.add(emailListCategory.get(i));
}
++i;
}
emailListCategory.removeAll(removeEmail);
removeEmail.clear();
// Watched on forum
i = 0;
for (String user : userListForum) {
if(userListCategory.contains(user)
|| !canReceiveNotification(topicNode, user, post.getOwner())) {
removeEmail.add(emailListForum.get(i));
}
++i;
}
emailListForum.removeAll(removeEmail);
removeEmail.clear();
// Watched on topic
i = 0;
for (String user : userListTopic) {
if(userListCategory.contains(user)
|| userListForum.contains(user)
|| !canReceiveNotification(topicNode, user, post.getOwner())) {
removeEmail.add(emailListTopic.get(i));
}
++i;
}
emailListTopic.removeAll(removeEmail);
// Owner Notify
if (isApprovePost) {
String owner = topicReader.string(EXO_OWNER);
String ownerTopicEmail = topicReader.string(EXO_IS_NOTIFY_WHEN_ADD_POST, StringUtils.EMPTY);
if (!CommonUtils.isEmpty(ownerTopicEmail)) {
try {
Node userOwner = userProfileHome.getNode(owner);
PropertyReader userReader = new PropertyReader(userOwner);
String email = userReader.string(EXO_EMAIL, StringUtils.EMPTY);
if(userReader.bool(EXO_IS_BANNED)) {
ownerTopicEmail = StringUtils.EMPTY;
} else if (!Utils.isEmpty(email)) {
ownerTopicEmail = email;
}
} catch (PathNotFoundException e) {
// owner not existing
ownerTopicEmail = StringUtils.EMPTY;
}
}
if(!CommonUtils.isEmpty(ownerTopicEmail)) {
emailListTopic.add(ownerTopicEmail);
}
}
//
emailListForum.addAll(forumReader.list(EXO_NOTIFY_WHEN_ADD_POST, new ArrayList<String>()));
//
String fullName = getScreenName(sProvider, post.getOwner());
messageBuilder.setOwner(CommonUtils.decodeSpecialCharToHTMLnumber(fullName));
messageBuilder.setId(post.getId());
messageBuilder.setAddType(Utils.POST);
messageBuilder.setAddName(post.getName());
messageBuilder.setMessage(post.getMessage());
messageBuilder.setCreatedDate(post.getCreatedDate());
if(Utils.isEmpty(messageBuilder.getLink())) {
messageBuilder.setLink(post.getLink());
}
// send email by category
if (emailListCategory.size() > 0) {
messageBuilder.setObjName(messageBuilder.getCatName());
messageBuilder.setWatchType(Utils.CATEGORY);
sendEmailNotification(emailListCategory, messageBuilder.getContentEmail());
}
// send email by forum
if (emailListForum.size() > 0) {
messageBuilder.setObjName(messageBuilder.getForumName());
messageBuilder.setWatchType(Utils.FORUM);
sendEmailNotification(emailListForum, messageBuilder.getContentEmail());
}
// send email by topic
if (emailListTopic.size() > 0) {
messageBuilder.setObjName(messageBuilder.getTopicName());
messageBuilder.setWatchType(Utils.TOPIC);
sendEmailNotification(emailListTopic, messageBuilder.getContentEmail());
}
}
}
}
public void sendNotification(String nodePath, Topic topic, Post post, MessageBuilder messageBuilder, boolean isApprovePost) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = sessionManager.getSession(sProvider);
if (!session.itemExists(nodePath)) {
return;
}
Node node = (Node) session.getItem(nodePath);
messageBuilder = getInfoMessageMove(sProvider, messageBuilder.getContent(), messageBuilder.getHeaderSubject(), false);
if (post == null) {
sendNotificationWhenCreateTopic(sProvider, node, topic, messageBuilder);
} else {
sendNotificationWhenCreatePost(sProvider, node, post, messageBuilder, isApprovePost);
}
} catch (Exception e) {
LOG.error("Failed to send notification.", e);
} finally {
sProvider.close();
}
}
public void modifyPost(List<Post> posts, int type) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumHomeNode = getForumHomeNode(sProvider);
for (Post post : posts) {
try {
String postPath = post.getPath();
String topicPath = postPath.substring(0, postPath.lastIndexOf("/"));
String forumPath = postPath.substring(0, topicPath.lastIndexOf("/"));
Node postNode = (Node) forumHomeNode.getSession().getItem(postPath);
PropertyReader postReader = new PropertyReader(postNode);
Node topicNode = (Node) forumHomeNode.getSession().getItem(topicPath);
Node forumNode = (Node) forumHomeNode.getSession().getItem(forumPath);
Calendar lastPostDate = topicNode.getProperty(EXO_LAST_POST_DATE).getDate();
Calendar postDate = postReader.calendar(EXO_CREATED_DATE);
long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong();
long newNumberAttach = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong();
long forumPostCount = forumNode.getProperty(EXO_POST_COUNT).getLong();
switch (type) {
case Utils.APPROVE: {
postNode.setProperty(EXO_IS_APPROVED, true);
post.setIsApproved(true);
//
addNotificationTask(topicNode.getPath(), null, post, new MessageBuilder(), true);
break;
}
case Utils.WAITING: {
if (post.getIsWaiting()) {
postNode.setProperty(EXO_IS_WAITING, true);
Node postLastNode = getLastDatePost(forumHomeNode, topicNode, postNode);
PropertyReader postLastNodeReader = new PropertyReader(postLastNode);
if (postLastNode != null) {
topicNode.setProperty(EXO_LAST_POST_DATE, postLastNodeReader.calendar(EXO_CREATED_DATE));
topicNode.setProperty(EXO_LAST_POST_BY, postLastNodeReader.string(EXO_OWNER));
}
newNumberAttach = newNumberAttach - postReader.l(EXO_NUMBER_ATTACH);
if (newNumberAttach < 0)
newNumberAttach = 0;
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach);
topicNode.setProperty(EXO_POST_COUNT, topicPostCount - 1);
forumNode.setProperty(EXO_POST_COUNT, forumPostCount - 1);
} else {
postNode.setProperty(EXO_IS_WAITING, false);
topicNode.setProperty(EXO_LAST_POST_DATE, postReader.calendar(EXO_CREATED_DATE));
topicNode.setProperty(EXO_LAST_POST_BY, postReader.string(EXO_OWNER));
newNumberAttach = newNumberAttach + postReader.l(EXO_NUMBER_ATTACH);
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach);
topicNode.setProperty(EXO_POST_COUNT, topicPostCount + 1);
//
addNotificationTask(topicNode.getPath(), null, post, new MessageBuilder(), false);
}
break;
}
case Utils.HIDDEN: {
if (post.getIsHidden()) {
postNode.setProperty(EXO_IS_HIDDEN, true);
Node postLastNode = getLastDatePost(forumHomeNode, topicNode, postNode);
PropertyReader postLastNodeReader = new PropertyReader(postLastNode);
if (postLastNode != null) {
topicNode.setProperty(EXO_LAST_POST_DATE, postLastNodeReader.calendar(EXO_CREATED_DATE));
topicNode.setProperty(EXO_LAST_POST_BY, postLastNodeReader.string(EXO_OWNER));
}
newNumberAttach = newNumberAttach - postReader.l(EXO_NUMBER_ATTACH);
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, Math.max(newNumberAttach, 0));
topicNode.setProperty(EXO_POST_COUNT, topicPostCount - 1);
forumNode.setProperty(EXO_POST_COUNT, forumPostCount - 1);
} else {
postNode.setProperty(EXO_IS_HIDDEN, false);
addNotificationTask(topicNode.getPath(), null, post, new MessageBuilder(), false);
}
break;
}
default:
break;
}
if (!post.getIsHidden() && post.getIsApproved() && (Utils.WAITING != type)) {
if (postDate.getTimeInMillis() > lastPostDate.getTimeInMillis()) {
topicNode.setProperty(EXO_LAST_POST_DATE, postDate);
topicNode.setProperty(EXO_LAST_POST_BY, post.getOwner());
}
newNumberAttach = newNumberAttach + postReader.l(EXO_NUMBER_ATTACH);
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttach);
topicNode.setProperty(EXO_POST_COUNT, topicPostCount + 1);
forumNode.setProperty(EXO_POST_COUNT, forumPostCount + 1);
}
if (forumNode.isNew()) {
forumNode.getSession().save();
} else {
forumNode.save();
}
//
getTotalJobWatting(sProvider, new HashSet<String>(new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>())));
} catch (PathNotFoundException e) {
LOG.error("Failed to modify post" + post.getName(), e);
}
}
} catch (Exception e) {
LOG.error("Failed to modify posts", e);
}
}
private Node getLastDatePost(Node forumHomeNode, Node node, Node postNode_) throws Exception {
QueryManager qm = forumHomeNode.getSession().getWorkspace().getQueryManager();
StringBuffer pathQuery = new StringBuffer();
pathQuery.append(JCR_ROOT).append(node.getPath()).append("/element(*,exo:post)[@exo:isHidden='false' and @exo:isApproved='true'] order by @exo:createdDate descending");
Query query = qm.createQuery(pathQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
Node postNode = null;
while (iter.hasNext()) {
postNode = iter.nextNode();
if (postNode.getName().equals(postNode_.getName())) {
continue;
} else {
break;
}
}
return postNode;
}
public Post removePost(String categoryId, String forumId, String topicId, String postId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Post post;
try {
Node CategoryNode = getCategoryHome(sProvider).getNode(categoryId);
post = getPost(categoryId, forumId, topicId, postId);
Node forumNode = CategoryNode.getNode(forumId);
Node topicNode = forumNode.getNode(topicId);
Node postNode = topicNode.getNode(postId);
long numberAttachs = postNode.getProperty(EXO_NUMBER_ATTACH).getLong();
String owner = postNode.getProperty(EXO_OWNER).getString();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node newProfileNode = userProfileNode.getNode(owner);
newProfileNode.setProperty(EXO_TOTAL_POST, newProfileNode.getProperty(EXO_TOTAL_POST).getLong() - 1);
newProfileNode.save();
} catch (PathNotFoundException e) {
LOG.debug("Failed to save category moderators ", e);
}
postNode.remove();
// update information: setPostCount, lastpost for Topic
if (!post.getIsHidden() && post.getIsApproved() && !post.getIsWaiting() && (post.getUserPrivate() == null || post.getUserPrivate().length == 1)) {
long topicPostCount = topicNode.getProperty(EXO_POST_COUNT).getLong() - 1;
topicNode.setProperty(EXO_POST_COUNT, topicPostCount);
long newNumberAttachs = topicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong();
if (newNumberAttachs > numberAttachs)
newNumberAttachs = newNumberAttachs - numberAttachs;
else
newNumberAttachs = 0;
topicNode.setProperty(EXO_NUMBER_ATTACHMENTS, newNumberAttachs);
}
NodeIterator nodeIterator = topicNode.getNodes();
/*
* long last = nodeIterator.getSize() - 1; nodeIterator.skip(last);
*/
while (nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
if (node.isNodeType(EXO_POST))
postNode = node;
}
topicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString());
topicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate());
forumNode.save();
// TODO: Thinking for update forum and user profile by node observation?
// setPostCount for Forum
if (!post.getIsHidden() && post.getIsApproved() && (post.getUserPrivate() == null || post.getUserPrivate().length == 1)) {
long forumPostCount = forumNode.getProperty(EXO_POST_COUNT).getLong() - 1;
forumNode.setProperty(EXO_POST_COUNT, forumPostCount);
forumNode.save();
} else if (post.getUserPrivate() == null || post.getUserPrivate().length == 1) {
getTotalJobWatting(sProvider, new HashSet<String>(new PropertyReader(forumNode).list(EXO_MODERATORS, new ArrayList<String>())));
}
return post;
} catch (Exception e) {
LOG.error("Failed to remove post in topic.");
return null;
}
}
public void movePost(String[] postPaths, String destTopicPath, boolean isCreatNewTopic, String mailContent, String link) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node forumHomeNode = getForumHomeNode(sProvider);
// Node Topic move Post
String srcTopicPath = postPaths[0];
srcTopicPath = srcTopicPath.substring(0, srcTopicPath.lastIndexOf("/"));
Node srcTopicNode = (Node) forumHomeNode.getSession().getItem(srcTopicPath);
Node srcForumNode = (Node) srcTopicNode.getParent();
Node destTopicNode = (Node) forumHomeNode.getSession().getItem(destTopicPath);
Node destForumNode = (Node) destTopicNode.getParent();
long totalAtt = 0;
long totalpost = (long) postPaths.length;
Node postNode = null;
boolean destModeratePost = false;
if (destTopicNode.hasProperty(EXO_IS_MODERATE_POST)) {
destModeratePost = destTopicNode.getProperty(EXO_IS_MODERATE_POST).getBoolean();
}
boolean srcModeratePost = false;
if (srcTopicNode.hasProperty(EXO_IS_MODERATE_POST)) {
srcModeratePost = srcTopicNode.getProperty(EXO_IS_MODERATE_POST).getBoolean();
}
PropertyReader destTopicReader = new PropertyReader(destTopicNode);
boolean isActiveByTopic = destTopicReader.bool(EXO_IS_APPROVED) && destTopicReader.bool(EXO_IS_ACTIVE)
&& destTopicReader.bool(EXO_IS_ACTIVE_BY_FORUM) && !destTopicReader.bool(EXO_IS_CLOSED)
&& !destTopicReader.bool(EXO_IS_WAITING);
boolean unAproved = false;
String path;
for (int i = 0; i < totalpost; ++i) {
// totalAtt = totalAtt + post.getNumberAttach();
path = postPaths[i];
String newPostPath = destTopicPath + path.substring(path.lastIndexOf("/"));
forumHomeNode.getSession().getWorkspace().move(path, newPostPath);
postPaths[i] = newPostPath;
// Node Post move
postNode = (Node) forumHomeNode.getSession().getItem(newPostPath);
postNode.setProperty(EXO_PATH, destForumNode.getName());
postNode.setProperty(EXO_CREATED_DATE, getGreenwichMeanTime());
postNode.setProperty(EXO_LINK, CommonUtils.getURI(link.replace("pathId", destTopicNode.getName())));
//
if (isCreatNewTopic && i == 0) {
postNode.setProperty(EXO_IS_FIRST_POST, true);
} else {
postNode.setProperty(EXO_IS_FIRST_POST, false);
}
if (!destModeratePost) {
postNode.setProperty(EXO_IS_APPROVED, true);
} else {
if (!postNode.getProperty(EXO_IS_APPROVED).getBoolean()) {
unAproved = true;
}
}
postNode.setProperty(EXO_IS_ACTIVE_BY_TOPIC, isActiveByTopic);
}
// set destTopicNode
destTopicNode.setProperty(EXO_NUMBER_ATTACHMENTS, destTopicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong() + totalAtt);
// update last post for destTopicNode
destTopicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString());
destTopicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate());
// set srcTopicNode
long temp = srcTopicNode.getProperty(EXO_POST_COUNT).getLong();
temp = temp - totalpost;
srcTopicNode.setProperty(EXO_POST_COUNT, Math.max(temp, -1));
temp = srcTopicNode.getProperty(EXO_NUMBER_ATTACHMENTS).getLong();
temp = temp - totalAtt;
srcTopicNode.setProperty(EXO_NUMBER_ATTACHMENTS, Math.max(temp, 0));
// update last post for srcTopicNode
NodeIterator nodeIterator = srcTopicNode.getNodes();
long posLast = nodeIterator.getSize() - 1;
nodeIterator.skip(posLast);
while (nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
if (node.isNodeType(EXO_POST))
postNode = node;
}
srcTopicNode.setProperty(EXO_LAST_POST_BY, postNode.getProperty(EXO_OWNER).getValue().getString());
srcTopicNode.setProperty(EXO_LAST_POST_DATE, postNode.getProperty(EXO_CREATED_DATE).getValue().getDate());
// set srcForumNode
temp = srcForumNode.getProperty(EXO_POST_COUNT).getLong();
temp = temp - totalpost;
srcForumNode.setProperty(EXO_POST_COUNT, Math.max(temp, 0));
if (forumHomeNode.isNew()) {
forumHomeNode.getSession().save();
} else {
forumHomeNode.save();
}
String categoryName = destForumNode.getParent().getProperty(EXO_NAME).getString();
String forumName = destForumNode.getProperty(EXO_NAME).getString();
String objectName = new StringBuilder("[").append(categoryName).append("][").append(forumName).append("] ").toString();
MessageBuilder messageBuilder = getInfoMessageMove(sProvider, mailContent, objectName, true);
String topicName = destTopicNode.getProperty(EXO_NAME).getString();
String ownerTopic = destTopicNode.getProperty(EXO_OWNER).getString();
messageBuilder.setCatName(categoryName);
messageBuilder.setForumName(forumName);
messageBuilder.setTopicName(CommonUtils.EMPTY_STR);
messageBuilder.setOwner(CommonUtils.decodeSpecialCharToHTMLnumber(getScreenName(sProvider, ownerTopic)));
messageBuilder.setHeaderSubject(messageBuilder.getHeaderSubject() + topicName);
messageBuilder.setAddType(topicName);
link = link.replaceFirst("pathId", destTopicNode.getName());
messageBuilder.setTypes(Utils.TOPIC, Utils.POST, "", "");
for (int i = 0; i < totalpost; ++i) {
postNode = (Node) forumHomeNode.getSession().getItem(postPaths[i]);
messageBuilder.setObjName(postNode.getProperty(EXO_NAME).getString());
messageBuilder.setLink(link + "/" + postNode.getName());
Set<String> set = new HashSet<String>();
// set email author this topic
set.add(getEmailUser(sProvider, postNode.getProperty(EXO_OWNER).getString()));
// set email watch this topic, forum, category parent of this post
set.addAll(calculateMoveEmail(destTopicNode));
// set email watch old category, forum, topic parent of this post
set.addAll(calculateMoveEmail(srcTopicNode));
if (!Utils.isEmpty(set.toArray(new String[set.size()]))) {
sendEmailNotification(new ArrayList<String>(set), messageBuilder.getContentEmailMoved());
}
}
Set<String> userIdsp = new HashSet<String>();
if (destModeratePost && srcModeratePost) {
if (srcForumNode.hasProperty(EXO_MODERATORS)) {
userIdsp.addAll(Utils.valuesToList(srcForumNode.getProperty(EXO_MODERATORS).getValues()));
}
if (unAproved && destForumNode.hasProperty(EXO_MODERATORS)) {
userIdsp.addAll(Utils.valuesToList(destForumNode.getProperty(EXO_MODERATORS).getValues()));
}
} else if (srcModeratePost && !destModeratePost) {
if (srcForumNode.hasProperty(EXO_MODERATORS)) {
userIdsp.addAll(Utils.valuesToList(srcForumNode.getProperty(EXO_MODERATORS).getValues()));
}
} else if (!srcModeratePost && destModeratePost) {
if (unAproved && destForumNode.hasProperty(EXO_MODERATORS)) {
userIdsp.addAll(Utils.valuesToList(destForumNode.getProperty(EXO_MODERATORS).getValues()));
}
}
if (!userIdsp.isEmpty()) {
getTotalJobWatting(sProvider, userIdsp);
}
}
private MessageBuilder getInfoMessageMove(SessionProvider sProvider, String defaultContent, String defaultSubject, boolean isMove) throws Exception {
MessageBuilder messageBuilder = new MessageBuilder();
try {
Node forumAdminNode = getAdminHome(sProvider).getNode(Utils.FORUMADMINISTRATION);
PropertyReader reader = new PropertyReader(forumAdminNode);
String property = (isMove) ? EXO_NOTIFY_EMAIL_MOVED : EXO_NOTIFY_EMAIL_CONTENT;
messageBuilder.setContent(reader.string(property, defaultContent));
if (reader.bool(EXO_ENABLE_HEADER_SUBJECT)) {
messageBuilder.setHeaderSubject(reader.string(EXO_HEADER_SUBJECT, defaultSubject));
} else {
messageBuilder.setHeaderSubject(defaultSubject);
}
} catch (Exception e) {
messageBuilder.setContent(defaultContent);
messageBuilder.setHeaderSubject(defaultSubject);
}
return messageBuilder;
}
public void mergeTopic(String srcTopicPath, String destTopicPath, String mailContent, String link) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node srcTopicNode = getCategoryHome(sProvider).getNode(srcTopicPath);
NodeIterator iter = srcTopicNode.getNodes();
List<Post> posts = new ArrayList<Post>();
Post post;
boolean isTopicWaiting = new PropertyReader(srcTopicNode).bool(EXO_IS_WAITING);
while (iter.hasNext()) {
post = new Post();
Node node = iter.nextNode();
if (node.isNodeType(EXO_POST)) {
if (new PropertyReader(node).bool(EXO_IS_FIRST_POST)) {
node.setProperty(EXO_IS_WAITING, isTopicWaiting);
node.save();
}
post.setPath(node.getPath());
post.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime());
posts.add(post);
}
}
if (posts.size() > 0) {
Collections.sort(posts, new Utils.DatetimeComparatorPostDESC());
String[] postPaths = new String[posts.size()];
int i = 0;
for (Post p : posts) {
postPaths[i] = p.getPath();
++i;
}
movePost(postPaths, destTopicPath, false, mailContent, link);
String ids[] = srcTopicPath.split("/");
removeTopic(ids[0], ids[1], srcTopicNode.getName());
}
} catch (Exception e) {
throw e;
}
}
public void splitTopic(Topic newTopic, Post fistPost, List<String> postPathMove, String mailContent, String link) throws Exception {
// save new topic
saveTopic(newTopic.getCategoryId(), newTopic.getForumId(), newTopic, true, true, new MessageBuilder());
// save first post
savePost(fistPost.getCategoryId(), fistPost.getForumId(), fistPost.getTopicId(), fistPost, false, new MessageBuilder());
// move all posts to new topic
movePost(postPathMove.toArray(new String[postPathMove.size()]), newTopic.getPath(), true, mailContent, link);
}
public void addTag(List<Tag> tags, String userName, String topicPath) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
boolean isAdd;
Node topicNode = (Node) getCategoryHome(sProvider).getSession().getItem(topicPath);
List<String> listId = new ArrayList<String>();
List<String> list = new ArrayList<String>();
if (topicNode.hasProperty(EXO_TAG_ID)) {
listId = Utils.valuesToList(topicNode.getProperty(EXO_TAG_ID).getValues());
}
list.addAll(listId);
String userIdAndTagId;
for (Tag tag : tags) {
isAdd = true;
userIdAndTagId = userName + ":" + tag.getId();
for (String string1 : listId) {
if (userIdAndTagId.equals(string1)) {
isAdd = false;
break;
}
}
if (isAdd) {
list.add(userIdAndTagId);
saveTag(tag);
}
}
topicNode.setProperty(EXO_TAG_ID, Utils.getStringsInList(list));
if (topicNode.isNew()) {
topicNode.getSession().save();
} else {
topicNode.save();
}
} catch (Exception e) {
LOG.error("Failed to add tags", e);
}
}
public void unTag(String tagId, String userName, String topicPath){
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
Node topicNode = (Node) categoryHome.getSession().getItem(topicPath);
List<String> oldTagsId = Utils.valuesToList(topicNode.getProperty(EXO_TAG_ID).getValues());
// remove in topic.
String userIdTagId = userName + ":" + tagId;
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder builder = new StringBuilder();
builder.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)[@exo:tagId='").append(userIdTagId).append("']");
Query query = qm.createQuery(builder.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
if (oldTagsId.contains(userIdTagId)) {
oldTagsId.remove(userIdTagId);
topicNode.setProperty(EXO_TAG_ID, oldTagsId.toArray(new String[oldTagsId.size()]));
if (topicNode.isNew()) {
topicNode.getSession().save();
} else {
topicNode.save();
}
}
Tag tag = getTag(tagId);
List<String> userTags = new ArrayList<String>();
userTags.addAll(Arrays.asList(tag.getUserTag()));
if (iter.getSize() == 1 && userTags.size() > 1) {
if (userTags.contains(userName)) {
userTags.remove(userName);
tag.setUserTag(userTags.toArray(new String[userTags.size()]));
Node tagNode = getTagHome(sProvider).getNode(tagId);
long count = tagNode.getProperty(EXO_USE_COUNT).getLong();
if (count > 1)
tagNode.setProperty(EXO_USE_COUNT, count - 1);
tagNode.setProperty(EXO_USER_TAG, userTags.toArray(new String[userTags.size()]));
tagNode.save();
}
} else if (iter.getSize() == 1 && userTags.size() == 1) {
Node tagHomNode = getTagHome(sProvider);
tagHomNode.getNode(tagId).remove();
tagHomNode.save();
} else if (iter.getSize() > 1) {
Node tagNode = getTagHome(sProvider).getNode(tagId);
long count = tagNode.getProperty(EXO_USE_COUNT).getLong();
if (count > 1)
tagNode.setProperty(EXO_USE_COUNT, count - 1);
tagNode.save();
}
} catch (Exception e) {
LOG.error("Failed to untag.", e);
}
}
public Tag getTag(String tagId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node tagNode = getTagHome(sProvider).getNode(tagId);
return getTagNode(tagNode);
} catch (Exception e) {
return null;
}
}
public List<String> getTagNameInTopic(String userAndTopicId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> tagNames = new ArrayList<String>();
try {
Node tagHome = getTagHome(sProvider);
QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager();
int t = userAndTopicId.indexOf(",");
String userId = userAndTopicId.substring(0, t);
NodeIterator iter = getTopicNodeIteratorByTag(sProvider, qm, userAndTopicId);
StringBuilder builder = new StringBuilder();
StringBuilder builder1 = new StringBuilder();
if (iter.getSize() > 0) {
Node node = (Node) iter.nextNode();
if (node.hasProperty(EXO_TAG_ID)) {
boolean b = true;
t = 0;
List<String> list = new ArrayList<String>();
for (String string : Utils.valuesToList(node.getProperty(EXO_TAG_ID).getValues())) {
String[] temp = string.split(":");
if (temp.length == 2) {
if (temp[0].equals(userId)) {
if (t == 0)
builder.append("(@exo:id != '").append(temp[1]).append("'");
else
builder.append(" and @exo:id != '").append(temp[1]).append("'");
list.add(temp[1]);
t = 1;
} else if (!list.contains(temp[1])) {
if (b)
builder1.append(" (@exo:id='").append(temp[1]).append("'");
else
builder1.append(" or @exo:id='").append(temp[1]).append("'");
b = false;
}
}
}
if (!b)
builder1.append(")");
if (t == 1)
builder.append(")");
}
}
if (builder1.length() == 0) {
return tagNames;
}
StringBuffer queryString = new StringBuffer();
queryString.append(JCR_ROOT).append(tagHome.getPath()).append("//element(*,exo:forumTag)");
boolean isQr = false;
if (builder.length() > 0) {
queryString.append("[").append(builder);
isQr = true;
}
if (builder1.length() > 0) {
if (isQr) {
queryString.append(" and ").append(builder1);
} else {
queryString.append("[").append(builder1);
isQr = true;
}
}
if (isQr)
queryString.append("]");
queryString.append("order by @exo:useCount descending, @exo:name ascending ");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
iter = query.execute().getNodes();
return getTagName(iter, tagNames);
} catch (Exception e) {
return tagNames;
}
}
private List<String> getTagName(NodeIterator iter, List<String> tagNames) {
StringBuilder str;
PropertyReader reader;
while (iter.hasNext()) {
reader = new PropertyReader((Node) iter.nextNode());
str = new StringBuilder(reader.string(EXO_NAME));
str.append(Utils.SPACE).append("<font color=\"Salmon\">(").append(reader.string(EXO_USE_COUNT)).append(")</font>");
tagNames.add(str.toString());
if (tagNames.size() == 5)
break;
}
return tagNames;
}
private NodeIterator getTopicNodeIteratorByTag(SessionProvider sProvider, QueryManager qm, String userAndTopicId) throws Exception {
Node categoryHome = getCategoryHome(sProvider);
StringBuffer queryString = new StringBuffer();
String topicId = userAndTopicId.substring(userAndTopicId.indexOf(",") + 1);
queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)[exo:id='").append(topicId).append("']");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
return query.execute().getNodes();
}
public List<String> getAllTagName(String keyValue, String userAndTopicId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> tagNames = new ArrayList<String>();
try {
Node tagHome = getTagHome(sProvider);
QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager();
int t = userAndTopicId.indexOf(",");
String userId = userAndTopicId.substring(0, t);
NodeIterator iter = getTopicNodeIteratorByTag(sProvider, qm, userAndTopicId);
StringBuilder builder = new StringBuilder();
if (iter.getSize() > 0) {
Node node = (Node) iter.nextNode();
if (node.hasProperty(EXO_TAG_ID)) {
t = 0;
for (String string : Utils.valuesToList(node.getProperty(EXO_TAG_ID).getValues())) {
String[] temp = string.split(":");
if (temp.length == 2 && temp[0].equals(userId)) {
if (t == 0)
builder.append("@exo:id != '").append(temp[1]).append("'");
else
builder.append(" and @exo:id != '").append(temp[1]).append("'");
t = 1;
}
}
}
}
StringBuffer queryString = new StringBuffer();
queryString.append(JCR_ROOT).append(tagHome.getPath()).append("//element(*,exo:forumTag)[(jcr:contains(@exo:name, '").append(keyValue).append("*'))");
if (builder.length() > 0) {
queryString.append(" and (").append(builder).append(")");
}
queryString.append("]order by @exo:useCount descending, @exo:name ascending ");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
iter = query.execute().getNodes();
return getTagName(iter, tagNames);
} catch (Exception e) {
return tagNames;
}
}
public List<Tag> getAllTags() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Tag> tags = new ArrayList<Tag>();
try {
Node tagHome = getTagHome(sProvider);
QueryManager qm = tagHome.getSession().getWorkspace().getQueryManager();
StringBuffer queryString = new StringBuffer(JCR_ROOT + tagHome.getPath() + "/element(*,exo:forumTag)");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
while (iter.hasNext()) {
tags.add(getTagNode((Node) iter.nextNode()));
}
return tags;
} catch (Exception e) {
return tags;
}
}
private Tag getTagNode(Node tagNode) throws RepositoryException {
Tag newTag = new Tag();
newTag.setId(tagNode.getName());
PropertyReader reader = new PropertyReader(tagNode);
newTag.setUserTag(reader.strings(EXO_USER_TAG, new String[] {}));
newTag.setName(reader.string(EXO_NAME, ""));
newTag.setUseCount(reader.l(EXO_USE_COUNT));
return newTag;
}
public List<Tag> getMyTagInTopic(String[] tagIds) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Tag> tags = new ArrayList<Tag>();
try {
Node tagHome = getTagHome(sProvider);
for (String id : tagIds) {
try {
tags.add(getTagNode(tagHome.getNode(id)));
} catch (Exception e) {
if (LOG.isDebugEnabled()){
LOG.debug(String.format("Failed to get tag node with id %s", id), e);
}
}
}
return tags;
} catch (Exception e) {
return tags;
}
}
public JCRPageList getTopicByMyTag(String userIdAndtagId, String strOrderBy) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder builder = new StringBuilder();
builder.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:topic)");
if (userIdAndtagId.indexOf(":") > 0) {
builder.append("[@exo:tagId='").append(userIdAndtagId).append("']");
} else {
builder.append("[jcr:contains(@exo:tagId,'").append(userIdAndtagId).append("')]");
}
builder.append(" order by @exo:isSticky descending");
if (Utils.isEmpty(strOrderBy)) {
builder.append(", @exo:lastPostDate descending");
} else {
builder.append(", @exo:").append(strOrderBy);
if (strOrderBy.indexOf("lastPostDate") < 0) {
builder.append(", @exo:lastPostDate descending");
}
}
String pathQuery = builder.toString();
Query query = qm.createQuery(pathQuery, Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true);
return pagelist;
} catch (Exception e) {
return null;
}
}
public void saveTag(Tag newTag) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node tagHome = getTagHome(sProvider);
Node newTagNode;
boolean isNew = false;
try {
newTagNode = tagHome.getNode(newTag.getId());
} catch (PathNotFoundException e) {
isNew = true;
String id = Utils.TAG + newTag.getName();
newTagNode = tagHome.addNode(id, EXO_FORUM_TAG);
newTagNode.setProperty(EXO_ID, id);
}
if (isNew) {
newTagNode.setProperty(EXO_USER_TAG, newTag.getUserTag());
newTagNode.setProperty(EXO_NAME, newTag.getName());
newTagNode.setProperty(EXO_USE_COUNT, 1);
} else {
List<String> userTags = Utils.valuesToList(newTagNode.getProperty(EXO_USER_TAG).getValues());
if (!userTags.contains(newTag.getUserTag()[0])) {
userTags.add(newTag.getUserTag()[0]);
newTagNode.setProperty(EXO_USER_TAG, userTags.toArray(new String[userTags.size()]));
}
long count = newTagNode.getProperty(EXO_USE_COUNT).getLong();
newTagNode.setProperty(EXO_USE_COUNT, count + 1);
}
if (tagHome.isNew()) {
tagHome.getSession().save();
} else {
tagHome.save();
}
} catch (Exception e) {
LOG.error("Failed to save tag.", e);
}
}
public JCRPageList getPageListUserProfile() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node userProfileHome = getUserProfileHome(sProvider);
QueryManager qm = userProfileHome.getSession().getWorkspace().getQueryManager();
StringBuilder strQuery = jcrPathLikeAndNotLike(EXO_FORUM_USER_PROFILE, userProfileHome.getPath());
strQuery.append(" AND (").append(EXO_IS_DISABLED).append(" IS NULL OR ").append(EXO_IS_DISABLED).append("<>'true')");
Query query = qm.createQuery(strQuery.toString(), Query.SQL);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
return new ForumPageList(iter, 10, strQuery.toString(), true);
} catch (Exception e) {
return null;
}
}
public JCRPageList searchUserProfile(String userSearch) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node userProfileHome = getUserProfileHome(sProvider);
QueryManager qm = userProfileHome.getSession().getWorkspace().getQueryManager();
StringBuilder strQuery = jcrPathLikeAndNotLike(EXO_FORUM_USER_PROFILE, userProfileHome.getPath());
strQuery.append(" AND (").append(EXO_USER_ID).append(" LIKE '%").append(userSearch).append("%'")
.append(" OR ").append(EXO_FIRST_NAME).append(" LIKE '%").append(userSearch).append("%'")
.append(" OR ").append(EXO_LAST_NAME).append(" LIKE '%").append(userSearch).append("%'")
.append(" OR ").append(EXO_FULL_NAME).append(" LIKE '%").append(userSearch).append("%'")
.append(" OR ").append(EXO_EMAIL).append(" LIKE '%").append(userSearch).append("%'")
.append(" OR ").append(EXO_USER_TITLE).append(" LIKE '%").append(userSearch).append("%'")
.append(") AND (").append(EXO_IS_DISABLED).append(" IS NULL OR ").append(EXO_IS_DISABLED).append("<>'true')");
Query query = qm.createQuery(strQuery.toString(), Query.SQL);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
return new ForumPageList(iter, 10, strQuery.toString(), true);
} catch (Exception e) {
return null;
}
}
public UserProfile getDefaultUserProfile(String userName, String ip) throws Exception {
UserProfile userProfile = new UserProfile();
if (userName == null || userName.length() <= 0)
return userProfile;
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node profileNode = getUserProfileNode(sProvider, userName);
PropertyReader reader = new PropertyReader(profileNode);
userProfile.setUserId(userName);
if (isAdminRole(userName)) {
userProfile.setUserRole((long) 0);
} else {
userProfile.setUserRole(reader.l(EXO_USER_ROLE, 2));
}
userProfile.setModerateForums(reader.strings(EXO_MODERATE_FORUMS, new String[] {}));
userProfile.setModerateCategory(reader.strings(EXO_MODERATE_CATEGORY, new String[] {}));
userProfile.setScreenName(getScreenName(userName, profileNode));
userProfile.setNewMessage(reader.l(EXO_NEW_MESSAGE));
userProfile.setTimeZone(reader.d(EXO_TIME_ZONE));
userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, userProfile.getShortDateFormat()));
userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, userProfile.getLongDateFormat()));
userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, userProfile.getTimeFormat()));
userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST, 10));
userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC, 10));
userProfile.setIsAutoWatchMyTopics(reader.bool(EXO_IS_AUTO_WATCH_MY_TOPICS));
userProfile.setIsAutoWatchTopicIPost(reader.bool(EXO_IS_AUTO_WATCH_TOPIC_I_POST));
userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {}));
userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {}));
userProfile.setIsBanned(reader.bool(EXO_IS_BANNED));
userProfile.setCollapCategories(reader.strings(EXO_COLLAP_CATEGORIES, new String[] {}));
userProfile.setEmail(reader.string(EXO_EMAIL, ""));
List<String> values = reader.list(EXO_READ_TOPIC, new ArrayList<String>());
String s = ":";
for (String str : values) {
if (str.indexOf(s) > 0) {
String[] array = str.split(s);
userProfile.setLastTimeAccessTopic(array[0], Long.parseLong(array[1]));
}
}
values = reader.list(EXO_READ_FORUM, new ArrayList<String>());
for (String str : values) {
if (str.indexOf(s) > 0) {
String[] array = str.split(s);
userProfile.setLastTimeAccessForum(array[0], Long.parseLong(array[1]));
}
}
if (userProfile.getIsBanned()) {
if (profileNode.hasProperty(EXO_BAN_UNTIL)) {
userProfile.setBanUntil(reader.l(EXO_BAN_UNTIL));
if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) {
profileNode.setProperty(EXO_IS_BANNED, false);
profileNode.save();
userProfile.setIsBanned(false);
}
}
} else if (ip != null) {
userProfile.setIsBanned(isBanIp(ip));
}
} catch (Exception e) {
userProfile.setUserId(userName);
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get default userprofile of user: " + userName, e);
}
}
return userProfile;
}
public UserProfile updateUserProfileSetting(UserProfile userProfile) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId());
PropertyReader reader = new PropertyReader(profileNode);
//
if (userProfile.getIsBanned()) {
userProfile.setBanUntil(reader.l(EXO_BAN_UNTIL));
if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) {
profileNode.setProperty(EXO_IS_BANNED, false);
profileNode.save();
userProfile.setIsBanned(false);
}
}
//
userProfile.setTimeZone(reader.d(ForumNodeTypes.EXO_TIME_ZONE));
userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, userProfile.getShortDateFormat()));
userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, userProfile.getLongDateFormat()));
userProfile.setModerateForums(reader.strings(EXO_MODERATE_FORUMS, new String[] {}));
userProfile.setModerateCategory(reader.strings(EXO_MODERATE_CATEGORY, new String[] {}));
userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC, 10));
userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST, 10));
userProfile.setBanReason(reader.string(EXO_BAN_REASON, ""));
userProfile.setBanCounter(Integer.parseInt(reader.string(EXO_BAN_COUNTER, "0")));
userProfile.setBanReasonSummary(reader.strings(EXO_BAN_REASON_SUMMARY, new String[] {}));
userProfile.setCreatedDateBan(reader.date(EXO_CREATED_DATE_BAN));
return userProfile;
}
public String getScreenName(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
return getScreenName(sProvider, userName);
} catch (Exception e) {
return userName;
}
}
private String getScreenName(SessionProvider sProvider, String userName) throws Exception {
try {
Node userProfile = getUserProfileNode(getUserProfileHome(sProvider), userName);
return getScreenName(userName, userProfile);
} catch (Exception e) {
return getScreenName(userName, null);
}
}
private String getScreenName(String userName, Node userProfile) throws Exception {
String userTemp = userName;
if (userProfile != null) {
PropertyReader reader = new PropertyReader(userProfile);
userName = reader.string(EXO_SCREEN_NAME, reader.string(EXO_FULL_NAME, userName));
}
return (userTemp.contains(Utils.DELETED)) ? "<s>" + ((userName.contains(Utils.DELETED)) ? userName.substring(0, userName.indexOf(Utils.DELETED)) : userName) + "</s>" : userName;
}
public boolean isBanIp(String ip) throws Exception {
return (getBanList().contains(ip)) ? true : false;
}
public UserProfile getUserSettingProfile(String userName) throws Exception {
UserProfile userProfile = new UserProfile();
if (userName == null || userName.length() <= 0)
return userProfile;
SessionProvider sProvider = CommonUtils.createSystemProvider();
Session session = sessionManager.getSession(sProvider);
try {
userProfile = getCachedDataStorage().getQuickProfile(userName);
Node profileNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation() + "/" + userName);
PropertyReader reader = new PropertyReader(profileNode);
//some information of profile has been loaded by getQuickProfile, don't loading anymore.
//userProfile.setUserId(userName);
//userProfile.setUserTitle(reader.string(EXO_USER_TITLE, ""));
userProfile.setScreenName(getScreenName(userName, profileNode));
userProfile.setSignature(reader.string(EXO_SIGNATURE, ""));
userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE, true));
//userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR, true));
userProfile.setIsAutoWatchMyTopics(reader.bool(EXO_IS_AUTO_WATCH_MY_TOPICS));
userProfile.setIsAutoWatchTopicIPost(reader.bool(EXO_IS_AUTO_WATCH_TOPIC_I_POST));
userProfile.setUserRole(reader.l(EXO_USER_ROLE));
userProfile.setTimeZone(reader.d(EXO_TIME_ZONE));
userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, ""));
userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, ""));
userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, ""));
userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST));
userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC));
} catch (Exception e) {
userProfile.setUserId(userName);
userProfile.setUserTitle(Utils.USER);
userProfile.setUserRole((long) 2);
// default Administration
if (isAdminRole(userName)) {
userProfile.setUserRole((long) 0);
userProfile.setUserTitle(Utils.ADMIN);
saveUserProfile(userProfile, false, false);
}
}
return userProfile;
}
public void saveUserSettingProfile(UserProfile userProfile) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId());
try {
profileNode.setProperty(EXO_USER_TITLE, userProfile.getUserTitle());
profileNode.setProperty(EXO_SCREEN_NAME, userProfile.getScreenName());
profileNode.setProperty(EXO_SIGNATURE, userProfile.getSignature());
profileNode.setProperty(EXO_IS_DISPLAY_SIGNATURE, userProfile.getIsDisplaySignature());
profileNode.setProperty(EXO_IS_DISPLAY_AVATAR, userProfile.getIsDisplayAvatar());
profileNode.setProperty(EXO_USER_ROLE, userProfile.getUserRole());
profileNode.setProperty(EXO_TIME_ZONE, userProfile.getTimeZone());
profileNode.setProperty(EXO_SHORT_DATEFORMAT, userProfile.getShortDateFormat());
profileNode.setProperty(EXO_LONG_DATEFORMAT, userProfile.getLongDateFormat());
profileNode.setProperty(EXO_TIME_FORMAT, userProfile.getTimeFormat());
profileNode.setProperty(EXO_MAX_POST, userProfile.getMaxPostInPage());
profileNode.setProperty(EXO_MAX_TOPIC, userProfile.getMaxTopicInPage());
profileNode.setProperty(EXO_IS_AUTO_WATCH_MY_TOPICS, userProfile.getIsAutoWatchMyTopics());
profileNode.setProperty(EXO_IS_AUTO_WATCH_TOPIC_I_POST, userProfile.getIsAutoWatchTopicIPost());
profileNode.save();
} catch (Exception e) {
LOG.error("Failed to save setting profile.", e);
}
}
public UserProfile getLastPostIdRead(UserProfile userProfile, String isOfForum) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node profileNode = getUserProfileNode(sProvider, userProfile.getUserId());
PropertyReader reader = new PropertyReader(profileNode);
if (isOfForum.equals("true")) {
userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {}));
} else if (isOfForum.equals("false")) {
userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {}));
} else {
userProfile.setLastReadPostOfForum(reader.strings(EXO_LAST_READ_POST_OF_FORUM, new String[] {}));
userProfile.setLastReadPostOfTopic(reader.strings(EXO_LAST_READ_POST_OF_TOPIC, new String[] {}));
}
return userProfile;
}
public void saveLastPostIdRead(String userId, String[] lastReadPostOfForum, String[] lastReadPostOfTopic) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
final ReentrantLock localLock = lock;
try {
localLock.lock(); // block until condition holds
Node profileNode = getUserProfileNode(sProvider, userId);
profileNode.setProperty(EXO_LAST_READ_POST_OF_FORUM, lastReadPostOfForum);
profileNode.setProperty(EXO_LAST_READ_POST_OF_TOPIC, lastReadPostOfTopic);
profileNode.getSession().save();
} catch (Exception e) {
LOG.debug("Failed to save last post id read.", e);
} finally {
localLock.unlock();
}
}
public List<String> getUserModerator(String userName, boolean isModeCate) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
List<String> list = new ArrayList<String>();
try {
Node profileNode = userProfileNode.getNode(userName);
if (isModeCate)
try {
list.addAll(Utils.valuesToList(profileNode.getProperty(EXO_MODERATE_CATEGORY).getValues()));
} catch (Exception e) {
if (LOG.isDebugEnabled()){
LOG.debug("Failed to get moderators of categories", e);
}
}
else
list.addAll(Utils.valuesToList(profileNode.getProperty(EXO_MODERATE_FORUMS).getValues()));
} catch (Exception e) {
if (LOG.isDebugEnabled()){
LOG.debug("Failed to get moderators of forums", e);
}
}
return list;
}
public void saveUserModerator(String userName, List<String> ids, boolean isModeCate) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node profileNode = userProfileNode.getNode(userName);
if (isModeCate)
profileNode.setProperty(EXO_MODERATE_CATEGORY, Utils.getStringsInList(ids));
else
profileNode.setProperty(EXO_MODERATE_FORUMS, Utils.getStringsInList(ids));
profileNode.save();
} catch (Exception e) {
LOG.error(String.format("Failed to set %s as moderator", userName));
}
}
private Node getUserProfileNode(Node profileHome, String userName) throws Exception {
try {
return profileHome.getNode(userName);
} catch (PathNotFoundException e) {
if (profileHome.hasNode(Utils.USER_PROFILE_DELETED)) {
Node deletedHome = profileHome.getNode(Utils.USER_PROFILE_DELETED);
return deletedHome.getNode(userName);
}
throw e;
}
}
public UserProfile getUserInfo(String userName) throws Exception {
UserProfile userProfile = new UserProfile();
if (userName == null || userName.length() <= 0)
return userProfile;
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
Node newProfileNode;
try {
newProfileNode = getUserProfileNode(userProfileNode, userName);
PropertyReader reader = new PropertyReader(newProfileNode);
userProfile.setUserId(userName);
userProfile.setScreenName(getScreenName(userName, newProfileNode));
userProfile.setFullName(reader.string(EXO_FULL_NAME));
userProfile.setFirstName(reader.string(EXO_FIRST_NAME));
userProfile.setLastName(reader.string(EXO_LAST_NAME));
userProfile.setEmail(reader.string(EXO_EMAIL));
if (isAdminRole(userName)) {
userProfile.setUserRole((long) 0); // admin role = 0
} else {
userProfile.setUserRole(reader.l(EXO_USER_ROLE));
}
userProfile.setUserTitle(reader.string(EXO_USER_TITLE, ""));
userProfile.setSignature(reader.string(EXO_SIGNATURE));
userProfile.setTotalPost(reader.l(EXO_TOTAL_POST));
userProfile.setTotalTopic(reader.l(EXO_TOTAL_TOPIC));
userProfile.setBookmark(reader.strings(EXO_BOOKMARK));
userProfile.setLastLoginDate(reader.date(EXO_LAST_LOGIN_DATE));
userProfile.setJoinedDate(reader.date(EXO_JOINED_DATE));
userProfile.setLastPostDate(reader.date(EXO_LAST_POST_DATE));
userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE));
userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR));
userProfile.setDisabled(reader.bool(EXO_IS_DISABLED, false));
} catch (PathNotFoundException e) {
userProfile.setUserId(userName);
userProfile.setUserTitle(Utils.USER);
userProfile.setUserRole((long) 2);
// default Administration
if (isAdminRole(userName)) {
userProfile.setUserRole((long) 0);
userProfile.setUserTitle(Utils.ADMIN);
saveUserProfile(userProfile, false, false);
}
}
return userProfile;
}
public List<UserProfile> getQuickProfiles(List<String> userList) throws Exception {
List<UserProfile> profiles = new ArrayList<UserProfile>();
try {
DataStorage storage = getCachedDataStorage();
for (String userName : userList) {
profiles.add(storage.getQuickProfile(userName));
}
} catch (Exception e) {
LOG.trace("\nUser Name must exist: " + e.getMessage() + "\n" + e.getCause());
}
return profiles;
}
public UserProfile getQuickProfile(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileHome = getUserProfileHome(sProvider);
//
return getUserProfile(getUserProfileNode(userProfileHome, userName));
}
public UserProfile getUserInformations(UserProfile userProfile) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileHome = getUserProfileHome(sProvider);
Node profileNode = getUserProfileNode(userProfileHome, userProfile.getUserId());
PropertyReader reader = new PropertyReader(profileNode);
userProfile.setFirstName(reader.string(EXO_FIRST_NAME, ""));
userProfile.setLastName(reader.string(EXO_LAST_NAME, ""));
userProfile.setFullName(reader.string(EXO_FULL_NAME, ""));
userProfile.setEmail(reader.string(EXO_EMAIL, ""));
userProfile.setDisabled(reader.bool(EXO_IS_DISABLED, false));
return userProfile;
}
public void saveUserProfile(UserProfile newUserProfile, boolean isOption, boolean isBan) throws Exception {
Node newProfileNode;
String userName = newUserProfile.getUserId();
if (userName == null || userName.length() <= 0)
return;
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileHome = getUserProfileHome(sProvider);
long role = 2;
try {
newProfileNode = userProfileHome.getNode(userName);
if (newProfileNode.hasProperty(EXO_USER_ROLE)) {
role = new PropertyReader(newProfileNode).l(EXO_USER_ROLE);
}
} catch (PathNotFoundException e) {
newProfileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE);
newProfileNode.setProperty(EXO_USER_ID, userName);
newProfileNode.setProperty(EXO_TOTAL_POST, 0);
newProfileNode.setProperty(EXO_TOTAL_TOPIC, 0);
newProfileNode.setProperty(EXO_READ_TOPIC, new String[] {});
newProfileNode.setProperty(EXO_READ_FORUM, new String[] {});
if (newUserProfile.getUserRole() >= 2) {
newUserProfile.setUserRole((long) 2);
}
if (isAdminRole(userName)) {
newUserProfile.setUserTitle(Utils.ADMIN);
}
}
newProfileNode.setProperty(EXO_USER_ROLE, newUserProfile.getUserRole());
newProfileNode.setProperty(EXO_USER_TITLE, newUserProfile.getUserTitle());
newProfileNode.setProperty(EXO_SCREEN_NAME, newUserProfile.getScreenName());
newProfileNode.setProperty(EXO_SIGNATURE, newUserProfile.getSignature());
newProfileNode.setProperty(EXO_IS_AUTO_WATCH_MY_TOPICS, newUserProfile.getIsAutoWatchMyTopics());
newProfileNode.setProperty(EXO_IS_AUTO_WATCH_TOPIC_I_POST,
newUserProfile.getIsAutoWatchTopicIPost());
newProfileNode.setProperty(EXO_MODERATE_CATEGORY, newUserProfile.getModerateCategory());
Calendar calendar = getGreenwichMeanTime();
if (newUserProfile.getLastLoginDate() != null)
calendar.setTime(newUserProfile.getLastLoginDate());
newProfileNode.setProperty(EXO_LAST_LOGIN_DATE, calendar);
newProfileNode.setProperty(EXO_IS_DISPLAY_SIGNATURE, newUserProfile.getIsDisplaySignature());
newProfileNode.setProperty(EXO_IS_DISPLAY_AVATAR, newUserProfile.getIsDisplayAvatar());
// UserOption
if (isOption) {
newProfileNode.setProperty(EXO_TIME_ZONE, newUserProfile.getTimeZone());
newProfileNode.setProperty(EXO_SHORT_DATEFORMAT, newUserProfile.getShortDateFormat());
newProfileNode.setProperty(EXO_LONG_DATEFORMAT, newUserProfile.getLongDateFormat());
newProfileNode.setProperty(EXO_TIME_FORMAT, newUserProfile.getTimeFormat());
newProfileNode.setProperty(EXO_MAX_POST, newUserProfile.getMaxPostInPage());
newProfileNode.setProperty(EXO_MAX_TOPIC, newUserProfile.getMaxTopicInPage());
}
// UserBan
if (isBan) {
if (newProfileNode.hasProperty(EXO_IS_BANNED)) {
if (!newProfileNode.getProperty(EXO_IS_BANNED).getBoolean() && newUserProfile.getIsBanned()) {
newProfileNode.setProperty(EXO_CREATED_DATE_BAN, getGreenwichMeanTime());
}
} else {
newProfileNode.setProperty(EXO_CREATED_DATE_BAN, getGreenwichMeanTime());
}
newProfileNode.setProperty(EXO_IS_BANNED, newUserProfile.getIsBanned());
newProfileNode.setProperty(EXO_BAN_UNTIL, newUserProfile.getBanUntil());
newProfileNode.setProperty(EXO_BAN_REASON, newUserProfile.getBanReason());
newProfileNode.setProperty(EXO_BAN_COUNTER, "" + newUserProfile.getBanCounter());
newProfileNode.setProperty(EXO_BAN_REASON_SUMMARY, newUserProfile.getBanReasonSummary());
}
if (userProfileHome.isNew()) {
userProfileHome.getSession().save();
} else {
userProfileHome.save();
}
if (role >= 2 && newUserProfile.getUserRole() < 2 && !isAdminRole(userName)) {
getTotalJobWaitingForModerator(userProfileHome.getSession(), userName);
}
}
public UserProfile getUserProfileManagement(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node userProfileNode = getUserProfileNode(getUserProfileHome(sProvider), userName);
return getUserProfile(userProfileNode);
} catch (Exception e) {
return null;
}
}
private UserProfile getUserProfile(Node userProfileNode) throws Exception {
UserProfile userProfile = new UserProfile();
String userName = userProfileNode.getName();
PropertyReader reader = new PropertyReader(userProfileNode);
userProfile.setUserId(userName);
userProfile.setUserTitle(reader.string(EXO_USER_TITLE, ""));
userProfile.setUserRole((userName.contains(Utils.DELETED)) ? 4 : reader.l(EXO_USER_ROLE, 2));
userProfile.setScreenName(getScreenName(userName, userProfileNode));
userProfile.setJoinedDate(reader.date(EXO_JOINED_DATE, new Date()));
userProfile.setIsDisplayAvatar(reader.bool(EXO_IS_DISPLAY_AVATAR));
userProfile.setNewMessage(reader.l(EXO_NEW_MESSAGE));
userProfile.setTimeZone(reader.d(EXO_TIME_ZONE));
userProfile.setShortDateFormat(reader.string(EXO_SHORT_DATEFORMAT, ""));
userProfile.setLongDateFormat(reader.string(EXO_LONG_DATEFORMAT, ""));
userProfile.setTimeFormat(reader.string(EXO_TIME_FORMAT, ""));
userProfile.setMaxPostInPage(reader.l(EXO_MAX_POST));
userProfile.setMaxTopicInPage(reader.l(EXO_MAX_TOPIC));
userProfile.setIsBanned(reader.bool(EXO_IS_BANNED));
userProfile.setDisabled(reader.bool(EXO_IS_DISABLED, false));
if (userProfile.getIsBanned()) {
if (userProfileNode.hasProperty(EXO_BAN_UNTIL)) {
userProfile.setBanUntil(reader.l(EXO_BAN_UNTIL));
if (userProfile.getBanUntil() <= getGreenwichMeanTime().getTimeInMillis()) {
userProfileNode.setProperty(EXO_IS_BANNED, false);
userProfileNode.save();
userProfile.setIsBanned(false);
}
}
}
userProfile.setTotalPost(reader.l(EXO_TOTAL_POST));
if (userProfile.getTotalPost() > 0) {
userProfile.setLastPostDate(reader.date(EXO_LAST_POST_DATE));
}
userProfile.setLastLoginDate(reader.date(EXO_LAST_LOGIN_DATE));
userProfile.setIsDisplaySignature(reader.bool(EXO_IS_DISPLAY_SIGNATURE, false));
if (userProfile.getIsDisplaySignature())
userProfile.setSignature(reader.string(EXO_SIGNATURE, ""));
return userProfile;
}
public void saveUserBookmark(String userName, String bookMark, boolean isNew) throws Exception {
Node newProfileNode;
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node userProfileNode = getUserProfileHome(sProvider);
try {
newProfileNode = userProfileNode.getNode(userName);
if (newProfileNode.hasProperty(EXO_BOOKMARK)) {
List<String> listOld = Utils.valuesToList(newProfileNode.getProperty(EXO_BOOKMARK).getValues());
List<String> listNew = new ArrayList<String>();
String pathNew = bookMark.substring(bookMark.lastIndexOf("//") + 1);
String pathOld = "";
boolean isAdd = true;
for (String string : listOld) {
pathOld = string.substring(string.lastIndexOf("//") + 1);
if (pathNew.equals(pathOld)) {
if (isNew) {
listNew.add(bookMark);
}
isAdd = false;
continue;
}
listNew.add(string);
}
if (isAdd) {
listNew.add(bookMark);
}
String[] bookMarks = listNew.toArray(new String[listNew.size()]);
newProfileNode.setProperty(EXO_BOOKMARK, bookMarks);
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
} else {
newProfileNode.setProperty(EXO_BOOKMARK, new String[] { bookMark });
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
}
} catch (PathNotFoundException e) {
newProfileNode = userProfileNode.addNode(userName, EXO_FORUM_USER_PROFILE);
newProfileNode.setProperty(EXO_USER_ID, userName);
newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER);
if (isAdminRole(userName)) {
newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN);
}
newProfileNode.setProperty(EXO_USER_ROLE, 2);
newProfileNode.setProperty(EXO_BOOKMARK, new String[] { bookMark });
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
}
} catch (Exception e) {
LOG.error("Failed to save UserBookmark.", e);
}
}
public void saveCollapsedCategories(String userName, String categoryId, boolean isAdd) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node newProfileNode;
Node userProfileHome = getUserProfileHome(sProvider);
try {
newProfileNode = userProfileHome.getNode(userName);
if (newProfileNode.hasProperty(EXO_COLLAP_CATEGORIES)) {
List<String> listCategoryId = Utils.valuesToList(newProfileNode.getProperty(EXO_COLLAP_CATEGORIES).getValues());
if (listCategoryId.contains(categoryId)) {
if (!isAdd) {
listCategoryId.remove(categoryId);
isAdd = true;
}
} else {
if (isAdd) {
listCategoryId.add(categoryId);
}
}
if (isAdd) {
String[] categoryIds = listCategoryId.toArray(new String[listCategoryId.size()]);
newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, categoryIds);
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
}
} else {
newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, new String[] { categoryId });
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
}
} catch (PathNotFoundException e) {
newProfileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE);
newProfileNode.setProperty(EXO_USER_ID, userName);
newProfileNode.setProperty(EXO_USER_TITLE, Utils.USER);
if (isAdminRole(userName)) {
newProfileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN);
}
newProfileNode.setProperty(EXO_USER_ROLE, 2);
newProfileNode.setProperty(EXO_COLLAP_CATEGORIES, new String[] { categoryId });
if (newProfileNode.isNew()) {
newProfileNode.getSession().save();
} else {
newProfileNode.save();
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to save collapsed categories.", e);
}
}
}
public void saveReadMessage(String messageId, String userName, String type) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node profileNode = userProfileNode.getNode(userName);
long totalNewMessage = 0;
boolean isNew = false;
try {
Node messageNode = profileNode.getNode(messageId);
if (messageNode.hasProperty(EXO_IS_UNREAD)) {
isNew = messageNode.getProperty(EXO_IS_UNREAD).getBoolean();
}
if (isNew) {// First read message.
messageNode.setProperty(EXO_IS_UNREAD, false);
}
} catch (PathNotFoundException e) {
LOG.error("Failed to save read massage", e);
}
if (type.equals(Utils.RECEIVE_MESSAGE) && isNew) {
if (profileNode.hasProperty(EXO_NEW_MESSAGE)) {
totalNewMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong();
if (totalNewMessage > 0) {
profileNode.setProperty(EXO_NEW_MESSAGE, (totalNewMessage - 1));
}
}
}
if (isNew) {
if (userProfileNode.isNew()) {
userProfileNode.getSession().save();
} else {
userProfileNode.save();
}
}
} catch (Exception e) {
LOG.error("Failed to save read message.");
}
}
public JCRPageList getPrivateMessage(String userName, String type) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node profileNode = userProfileNode.getNode(userName);
QueryManager qm = profileNode.getSession().getWorkspace().getQueryManager();
String pathQuery = JCR_ROOT + XPathUtils.escapeIllegalXPathName(profileNode.getPath()) + "/element(*,exo:privateMessage)[@exo:type='" + type + "'] order by @exo:receivedDate descending";
Query query = qm.createQuery(pathQuery, Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
JCRPageList pagelist = new ForumPageList(iter, 10, pathQuery, true);
return pagelist;
} catch (Exception e) {
LOG.error("Fail to get private message.", e);
return null;
}
}
public long getNewPrivateMessage(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node profileNode = userProfileNode.getNode(userName);
if (!profileNode.getProperty(EXO_IS_BANNED).getBoolean()) {
return profileNode.getProperty(EXO_NEW_MESSAGE).getLong();
}
} catch (PathNotFoundException e) {
return -1;
}
return -1;
}
public void savePrivateMessage(ForumPrivateMessage privateMessage) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
Node profileNode = null;
Node profileNodeFirst = null;
Node messageNode = null;
String sendTo = privateMessage.getSendTo();
sendTo = sendTo.replaceAll(";", ",");
String[] strUserNames = sendTo.split(",");
List<String> userNames;
try {
userNames = ForumServiceUtils.getUserPermission(strUserNames);
} catch (Exception e) {
userNames = Arrays.asList(strUserNames);
}
String id;
String userNameFirst = privateMessage.getFrom();
try {
profileNodeFirst = userProfileNode.getNode(userNameFirst);
} catch (PathNotFoundException e) {
profileNodeFirst = addNodeUserProfile(sProvider, userNameFirst);
}
long totalMessage = 0;
if (profileNodeFirst != null) {
id = userNameFirst + IdGenerator.generate();
messageNode = profileNodeFirst.addNode(id, EXO_PRIVATE_MESSAGE);
messageNode.setProperty(EXO_FROM, privateMessage.getFrom());
messageNode.setProperty(EXO_SEND_TO, privateMessage.getSendTo());
messageNode.setProperty(EXO_NAME, privateMessage.getName());
messageNode.setProperty(EXO_MESSAGE, privateMessage.getMessage());
messageNode.setProperty(EXO_RECEIVED_DATE, getGreenwichMeanTime());
messageNode.setProperty(EXO_IS_UNREAD, true);
messageNode.setProperty(EXO_TYPE, Utils.RECEIVE_MESSAGE);
}
StringBuilder sent = new StringBuilder();
for (String userName : userNames) {
if (userName.equals(userNameFirst))
continue;
try {
profileNode = userProfileNode.getNode(userName);
totalMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong() + 1;
id = profileNode.getPath() + "/" + userName + IdGenerator.generate();
userProfileNode.getSession().getWorkspace().copy(messageNode.getPath(), id);
profileNode.setProperty(EXO_NEW_MESSAGE, totalMessage);
} catch (Exception e) {
profileNode = addNodeUserProfile(sProvider, userName);
id = profileNode.getPath() + "/" + userName + IdGenerator.generate();
userProfileNode.getSession().getWorkspace().copy(messageNode.getPath(), id);
profileNode.setProperty(EXO_NEW_MESSAGE, 1);
}
if(sent.length() > 0) {
sent.append(",");
}
sent.append(userName);
}
// send notification message for user
privateMessage.setType("PrivateMessage");
//
privateMessage.setSendTo(sent.toString());
sendNotificationMessage(privateMessage);
if (messageNode != null) {
messageNode.setProperty(EXO_TYPE, Utils.SEND_MESSAGE);
}
if (userProfileNode.isNew()) {
userProfileNode.getSession().save();
} else {
userProfileNode.save();
}
}
private Node addNodeUserProfile(SessionProvider sProvider, String userName) throws Exception {
Node userProfileHome = getUserProfileHome(sProvider);
Node profileNode = userProfileHome.addNode(userName, EXO_FORUM_USER_PROFILE);
profileNode.setProperty(EXO_USER_ID, userName);
profileNode.setProperty(EXO_USER_TITLE, Utils.USER);
if (isAdminRole(userName)) {
profileNode.setProperty(EXO_USER_ROLE, 0);
profileNode.setProperty(EXO_USER_TITLE, Utils.ADMIN);
}
profileNode.setProperty(EXO_USER_ROLE, 2);
if (userProfileHome.isNew()) {
userProfileHome.getSession().save();
} else {
userProfileHome.save();
}
return profileNode;
}
public void removePrivateMessage(String messageId, String userName, String type) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node userProfileNode = getUserProfileHome(sProvider);
try {
Node profileNode = userProfileNode.getNode(userName);
Node messageNode = profileNode.getNode(messageId);
if (type.equals(Utils.RECEIVE_MESSAGE)) {
if (messageNode.hasProperty(EXO_IS_UNREAD)) {
if (messageNode.getProperty(EXO_IS_UNREAD).getBoolean()) {
long totalMessage = profileNode.getProperty(EXO_NEW_MESSAGE).getLong();
if (totalMessage > 0) {
profileNode.setProperty(EXO_NEW_MESSAGE, (totalMessage - 1));
}
}
}
}
messageNode.remove();
profileNode.save();
} catch (PathNotFoundException e) {
LOG.error("Failed to remove private message", e);
}
}
public ForumSubscription getForumSubscription(String userId){
SessionProvider sProvider = CommonUtils.createSystemProvider();
ForumSubscription forumSubscription = new ForumSubscription();
try {
Node subscriptionNode = getUserProfileHome(sProvider).getNode(userId + "/" + Utils.FORUM_SUBSCRIOTION + userId);
PropertyReader reader = new PropertyReader(subscriptionNode);
forumSubscription.setCategoryIds(reader.strings(EXO_CATEGORY_IDS, new String[] {}));
forumSubscription.setForumIds(reader.strings(EXO_FORUM_IDS, new String[] {}));
forumSubscription.setTopicIds(reader.strings(EXO_TOPIC_IDS, new String[] {}));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Failed to get forum subscription for user %s", userId), e);
}
}
return forumSubscription;
}
public void saveForumSubscription(ForumSubscription forumSubscription, String userId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node profileNode = getUserProfileHome(sProvider).getNode(userId);
Node subscriptionNode;
String id = Utils.FORUM_SUBSCRIOTION + userId;
try {
subscriptionNode = profileNode.getNode(id);
} catch (PathNotFoundException e) {
subscriptionNode = profileNode.addNode(id, EXO_FORUM_SUBSCRIPTION);
}
subscriptionNode.setProperty(EXO_CATEGORY_IDS, forumSubscription.getCategoryIds());
subscriptionNode.setProperty(EXO_FORUM_IDS, forumSubscription.getForumIds());
subscriptionNode.setProperty(EXO_TOPIC_IDS, forumSubscription.getTopicIds());
if (profileNode.isNew()) {
profileNode.getSession().save();
} else {
profileNode.save();
}
} catch (Exception e) {
LOG.error("Failed to save forum subscription.", e);
}
}
private String[] getValueProperty(Node node, String property, String objectId) throws Exception {
List<String> list = new ArrayList<String>();
if (node.hasProperty(property)) {
list.addAll(Utils.valuesToList(node.getProperty(property).getValues()));
if (!list.contains(objectId))
list.add(objectId);
} else {
list.add(objectId);
}
return list.toArray(new String[list.size()]);
}
public ForumStatistic getForumStatistic() throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
ForumStatistic forumStatistic = new ForumStatistic();
try {
Node forumStatisticNode = getForumStatisticsNode(sProvider);
PropertyReader reader = new PropertyReader(forumStatisticNode);
forumStatistic.setPostCount(reader.l(EXO_POST_COUNT, 0));
forumStatistic.setTopicCount(reader.l(EXO_TOPIC_COUNT, 0));
forumStatistic.setMembersCount(reader.l(EXO_MEMBERS_COUNT, 0));
forumStatistic.setActiveUsers(reader.l(EXO_ACTIVE_USERS, 0));
forumStatistic.setNewMembers(reader.string(EXO_NEW_MEMBERS, ""));
forumStatistic.setMostUsersOnline(reader.string(EXO_MOST_USERS_ONLINE, ""));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to load forum statistics", e);
}
} finally {
sProvider.close();
}
return forumStatistic;
}
public void saveForumStatistic(ForumStatistic forumStatistic) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Node forumStatisticNode = getForumStatisticsNode(sProvider);
forumStatisticNode.setProperty(EXO_POST_COUNT, forumStatistic.getPostCount());
forumStatisticNode.setProperty(EXO_TOPIC_COUNT, forumStatistic.getTopicCount());
forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, forumStatistic.getMembersCount());
forumStatisticNode.setProperty(EXO_ACTIVE_USERS, forumStatistic.getActiveUsers());
forumStatisticNode.setProperty(EXO_MOST_USERS_ONLINE, forumStatistic.getMostUsersOnline());
if (!Utils.isEmpty(forumStatistic.getNewMembers()))
forumStatisticNode.setProperty(EXO_NEW_MEMBERS, forumStatistic.getNewMembers());
if (forumStatisticNode.isNew()) {
forumStatisticNode.getSession().save();
} else {
forumStatisticNode.save();
}
} catch (Exception e) {
LOG.error("Failed to save forum statistics", e);
} finally {
sProvider.close();
}
}
public Object getObjectNameByPath(String path) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Object object;
try {
if (path.indexOf(KSDataLocation.Locations.FORUM_CATEGORIES_HOME) < 0 && (path.indexOf(Utils.CATEGORY) >= 0)) {
path = getCategoryHome(sProvider).getPath() + "/" + path;
} else if(path.indexOf(Utils.TAG) == 0){
path = getTagHome(sProvider).getPath() + "/" + path;
}
Node myNode = (Node) getForumHomeNode(sProvider).getSession().getItem(path);
if (path.indexOf(Utils.POST) > 0) {
Post post = new Post();
post.setId(myNode.getName());
post.setPath(path);
post.setName(myNode.getProperty(EXO_NAME).getString());
object = post;
} else if (path.indexOf(Utils.TOPIC) > 0) {
Topic topic = new Topic();
topic.setId(myNode.getName());
topic.setPath(path);
topic.setTopicName(myNode.getProperty(EXO_NAME).getString());
object = topic;
} else if (path.indexOf(Utils.FORUM) > 0 && (path.lastIndexOf(Utils.FORUM) > path.indexOf(Utils.CATEGORY))) {
Forum forum = new Forum();
forum.setId(myNode.getName());
forum.setPath(path);
forum.setForumName(myNode.getProperty(EXO_NAME).getString());
object = forum;
} else if (path.indexOf(Utils.CATEGORY) > 0) {
Category category = new Category();
category.setId(myNode.getName());
category.setPath(path);
category.setCategoryName(myNode.getProperty(EXO_NAME).getString());
object = category;
} else if (path.indexOf(Utils.TAG) > 0) {
Tag tag = new Tag();
tag.setId(myNode.getName());
tag.setName(myNode.getProperty(EXO_NAME).getString());
object = tag;
} else
return null;
return object;
} catch (RepositoryException e) {
return null;
}
}
public Object getObjectNameById(String id, String type) throws Exception {
Object object = null;
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node node = getNodeById(sProvider, id, type);
if (type.equals(Utils.CATEGORY)) {
Category category = getCategory(node);
object = category;
} else if (type.equals(Utils.FORUM)) {
Forum forum = getForum(node);
object = forum;
} else if (type.equals(Utils.TOPIC)) {
Topic topic = getTopicNode(node);
object = topic;
} else {
Post post = getPost(node);
object = post;
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can not get " + type + " by Id: " + id, e);
}
}
return object;
}
private Node getNodeById(SessionProvider sProvider, String id, String type) {
try {
Node categoryHome = getCategoryHome(sProvider);
if (type.equals(Utils.CATEGORY))
return categoryHome.getNode(id);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer stringBuffer = new StringBuffer(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,exo:").append(type)
.append(")[(@").append(EXO_ID).append("='").append(id).append("') or (fn:name()='").append(id).append("')]");
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
if (iter.getSize() > 0) return iter.nextNode();
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Can not get Node by Id: " + id, e);
}
}
return null;
}
public List<ForumLinkData> getAllLink(String strQueryCate, String strQueryForum) throws Exception {
List<ForumLinkData> forumLinks = new ArrayList<ForumLinkData>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer queryString = new StringBuffer();
queryString.append(JCR_ROOT)
.append(categoryHome.getPath())
.append("/element(*,exo:forumCategory)")
.append(strQueryCate)
.append(" order by @exo:categoryOrder ascending, @exo:createdDate ascending");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
ForumLinkData linkData;
while (iter.hasNext()) {
linkData = new ForumLinkData();
Node cateNode = iter.nextNode();
linkData.setId(cateNode.getName());
linkData.setName(cateNode.getProperty(EXO_NAME).getString());
linkData.setType(Utils.CATEGORY);
linkData.setPath(cateNode.getName());
forumLinks.add(linkData);
{
queryString = new StringBuffer();
queryString.append(JCR_ROOT)
.append(cateNode.getPath())
.append("/element(*,exo:forum)")
.append(strQueryForum)
.append(" order by @exo:forumOrder ascending,@exo:createdDate ascending");
query = qm.createQuery(queryString.toString(), Query.XPATH);
result = query.execute();
NodeIterator iterForum = result.getNodes();
while (iterForum.hasNext()) {
linkData = new ForumLinkData();
Node forumNode = iterForum.nextNode();
linkData.setId(forumNode.getName());
linkData.setName(forumNode.getProperty(EXO_NAME).getString());
linkData.setType(Utils.FORUM);
linkData.setPath(cateNode.getName() + "/" + forumNode.getName());
if (forumNode.hasProperty(EXO_IS_LOCK))
linkData.setIsLock(forumNode.getProperty(EXO_IS_LOCK).getBoolean());
if (forumNode.hasProperty(EXO_IS_CLOSED))
linkData.setIsClosed(forumNode.getProperty(EXO_IS_CLOSED).getBoolean());
forumLinks.add(linkData);
}
}
}
return forumLinks;
}
public List<ForumSearchResult> getQuickSearch(String textQuery, String type_, String pathQuery, String userId, List<String> listCateIds, List<String> listForumIds, List<String> forumIdsOfModerator) throws Exception {
List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
// Check path query
if (pathQuery == null || pathQuery.length() <= 0) {
pathQuery = categoryHome.getPath();
}
textQuery = StringUtils.replace(textQuery, "'", "'");
String[] values = type_.split(",");// user(admin or not admin), type(forum, topic, post)
boolean isAdmin = false;
if (values[0].equals("true"))
isAdmin = true;
String types[] = new String[] { Utils.CATEGORY, Utils.FORUM, Utils.TOPIC, Utils.POST };
if (!values[1].equals("all")) {
types = values[1].split("/");
}
boolean isAnd = false;
String searchBy = null;
List<String> listOfUser = new ArrayList<String>();
// If user isn't admin , get all membership of user
if (!isAdmin) {
listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null);
// Get all category & forum that user can view
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, EXO_USER_PRIVATE);
listCateIds = mapList.get(Utils.CATEGORY);
listForumIds = mapList.get(Utils.FORUM);
}
for (String type : types) {
StringBuffer queryString = new StringBuffer();
// select * from exo:type -- category, forum ,topic , post
queryString.append(JCR_ROOT).append(pathQuery).append("//element(*,exo:").append(type).append(")");
queryString.append("[");
// if search in category and list category that user can view not null
if (type.equals(Utils.CATEGORY)) {
if (listCateIds != null && listCateIds.size() > 0) {
queryString.append("(");
// select all category have name in list user can view
for (int i = 0; i < listCateIds.size(); i++) {
queryString.append("fn:name() = '").append(listCateIds.get(i)).append("'");
if (i < listCateIds.size() - 1)
queryString.append(" or ");
}
queryString.append(") and ");
}
// Select all forum that user can view
} else if (listForumIds != null && listForumIds.size() > 0) {
if (type.equals(Utils.FORUM))
searchBy = "fn:name()";
else
searchBy = "@exo:path";
queryString.append("(");
for (int i = 0; i < listForumIds.size(); i++) {
queryString.append(searchBy).append("='").append(listForumIds.get(i)).append("'");
if (i < listForumIds.size() - 1)
queryString.append(" or ");
}
queryString.append(") and ");
}
// Append text query
if (textQuery != null && textQuery.length() > 0 && !textQuery.equals("null")) {
queryString.append("(jcr:contains(., '").append(textQuery).append("'))");
isAnd = true;
}
// if user isn't admin
if (!isAdmin) {
StringBuilder builder = new StringBuilder();
// check user if user is moderator
if (forumIdsOfModerator != null && !forumIdsOfModerator.isEmpty()) {
for (String string : forumIdsOfModerator) {
builder.append(" or (@exo:path='").append(string).append("')");
}
}
// search forum not close in this user is moderator
if (type.equals(Utils.FORUM)) {
if (isAnd)
queryString.append(" and ");
queryString.append("(@exo:isClosed='false'");
for (String forumId : forumIdsOfModerator) {
queryString.append(" or fn:name()='").append(forumId).append("'");
}
queryString.append(")");
} else {
// search topic
if (type.equals(Utils.TOPIC)) {
if (isAnd)
queryString.append(" and ");
queryString.append("((@exo:isClosed='false' and @exo:isWaiting='false' and @exo:isApproved='true' and @exo:isActive='true' and @exo:isActiveByForum='true')");
if (builder.length() > 0) {
queryString.append(builder);
}
queryString.append(")");
String str = Utils.buildXpathByUserInfo(EXO_CAN_VIEW, listOfUser);
if (!Utils.isEmpty(str)) {
if (isAnd){
queryString.append(" and ");
}
queryString.append("(@").append(Utils.EXO_OWNER).append("='").append(userId).append("' or ")
.append(Utils.buildXpathHasProperty(EXO_CAN_VIEW)).append(" or ").append(str)
.append(")");
}
// seach post
} else if (type.equals(Utils.POST)) {
if (isAnd)
queryString.append(" and ");
queryString.append("((@exo:isApproved='true' and @exo:isHidden='false' and @exo:isActiveByTopic='true')");
if (builder.length() > 0) {
queryString.append(builder);
}
queryString.append(") and (@exo:userPrivate='exoUserPri'").append(" or @exo:userPrivate='").append(userId).append("') and @exo:isFirstPost='false'");
}
}
} else {
if (type.equals(Utils.POST)) {
if (isAnd)
queryString.append(" and ");
queryString.append("(@exo:userPrivate='exoUserPri'").append(" or @exo:userPrivate='").append(userId).append("') and @exo:isFirstPost='false'");
}
}
queryString.append("]");
// System.out.println("\n\n=======>"+queryString.toString());
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
// System.out.println("\n\n=======>iter: "+iter.getSize());
while (iter.hasNext()) {
Node nodeObj = iter.nextNode();
listSearchEvent.add(setPropertyForForumSearch(nodeObj, type));
}
if (type.equals(Utils.POST)) {
listSearchEvent.addAll(getSearchByAttachment(categoryHome, pathQuery, textQuery, listForumIds, listOfUser, isAdmin, ""));
}
}
// System.out.println("\n\n=======>listSearchEvent: "+listSearchEvent.size());
if (!isAdmin && listSearchEvent.size() > 0) {
List<String> categoryCanView = new ArrayList<String>();
List<String> forumCanView = new ArrayList<String>();
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, new ArrayList<String>(), EXO_VIEWER);
categoryCanView = mapList.get(Utils.CATEGORY);
forumCanView.addAll(getCachedDataStorage().getForumUserCanView(listOfUser, listForumIds));
if (categoryCanView.size() > 0 || forumCanView.size() > 0)
listSearchEvent = removeItemInList(listSearchEvent, forumCanView, categoryCanView);
}
} catch (Exception e) {
throw e;
}
return listSearchEvent;
}
public List<ForumSearchResult> getUnifiedSearch(String textQuery, String userId, Integer offset, Integer limit, String sort, String order) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<ForumSearchResult> list = new ArrayList<ForumSearchResult>();
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
//String rootPath = categoryHome.getPath();
//process query for asterisk
textQuery = CommonUtils.processUnifiedSearchSearchCondition(textQuery);
String asteriskQuery = CommonUtils.normalizeUnifiedSearchInput(textQuery);
if (Utils.isEmpty(asteriskQuery)) return list;
boolean isAdmin = isAdminRole(userId);
List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null);
List<String> listForumIds = getCachedDataStorage().getForumUserCanView(listOfUser, new ArrayList<String>());
//for (String type : types) {
StringBuilder queryString = buildSQLQueryUnifiedSearch(listForumIds, asteriskQuery, textQuery, isAdmin, sort, order, userId, listOfUser);
LOG.debug("UnifiedSearch statement query: " + queryString.toString());
QueryImpl query = (QueryImpl)qm.createQuery(queryString.toString(), Query.SQL);
query.setLimit(30);
query.setOffset(offset);
//query.setCaseInsensitiveOrder(true);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
//RowIterator rowIterator = result.getRows();
while (iter.hasNext() && limit > 0) {
Node nodeObj = iter.nextNode();
//Row row = rowIterator.nextRow();
if(hasPermssionViewerPost(nodeObj, listOfUser) == false) {
continue;
}
list.add(setPropertyUnifiedSearch(nodeObj, textQuery));
limit--;
}
} catch (Exception e) {
throw e;
}
//
return UnifiedSearchOrder.processOrder(list, sort, order);
}
private StringBuilder buildSQLQueryUnifiedSearch(List<String> listForumIds, String asteriskQuery,
String textQuery, boolean isAdmin, String sort, String order,
String userId, List<String> listOfUser) {
StringBuilder queryString = new StringBuilder();
queryString.append("select exo:name, exo:message, rep:excerpt() from exo:post where ");
if (listForumIds != null && listForumIds.size() > 0) {
queryString.append("(");
for (int i = 0; i < listForumIds.size(); i++) {
queryString.append(EXO_PATH).append("='").append(listForumIds.get(i)).append("'");
if (i < listForumIds.size() - 1)
queryString.append(" or ");
}
queryString.append(") and ");
}
queryString.append("(")
.append("CONTAINS (exo:message, '").append(asteriskQuery).append("')")
.append(" or (exo:isFirstPost='true' and ")
.append("CONTAINS (exo:name, '").append(asteriskQuery).append("'))")
.append(")");
// if user isn't admin
if (!isAdmin) {
queryString.append(" and ");
queryString.append("(exo:isApproved='true' and exo:isHidden='false' and exo:isActiveByTopic='true')");
queryString.append(" and (exo:userPrivate='exoUserPri'").append(" or exo:userPrivate='").append(userId).append("')");
} else {
queryString.append(" and ");
queryString.append("(exo:userPrivate='exoUserPri'").append(" or exo:userPrivate='").append(userId).append("')");
}
if ("date".equalsIgnoreCase(sort)) {
queryString.append(" order by ").append(EXO_CREATED_DATE);
} else if ("title".equalsIgnoreCase(sort) || Utils.isEmpty(sort)) {
queryString.append(" order by ").append(EXO_NAME);
} if("relevancy".equalsIgnoreCase(sort)) {
queryString.append(" order by ").append(JCR_SCORE);
}
queryString.append(" ").append(order);
return queryString;
}
private boolean hasPermssionViewerPost(Node postNode, List<String> listOfUser) throws Exception {
Node topicNode = postNode.getParent();
PropertyReader reader = new PropertyReader(topicNode);
List<String> listOfCanviewrs = reader.list(EXO_CAN_VIEW, new ArrayList<String>());
if (listOfUser != null && listOfUser.size() > 0 && reader.string(EXO_OWNER, "").equals(listOfUser.get(0))) {
return true;
}
return listOfCanviewrs.isEmpty() || Utils.hasPermission(listOfCanviewrs, listOfUser);
}
private ForumSearchResult setPropertyUnifiedSearch(Node nodeObj, String originQuery) throws Exception {
ForumSearchResult forumSearch = setPropertyForForumSearch(nodeObj, Utils.POST);
//forumSearch.setExcerpt(originQuery);
//forumSearch.setRelevancy(1);
try {
//
forumSearch.setRelevancy(1);
originQuery = CommonUtils.removeSpecialCharacterForUnifiedSearch(originQuery);
//
String excerpt = highlightText(nodeObj.getProperty(EXO_MESSAGE).getString(), originQuery);
// if excerpt does not contain highlight text and text query, using field
// name to display excerpt
if (!HIGHLIHT_PATTERN.matcher(excerpt).find()
&& excerpt.toLowerCase().indexOf(originQuery) < 0) {
excerpt = highlightText(nodeObj.getProperty(EXO_NAME).getString(), originQuery);
}
forumSearch.setExcerpt(excerpt);
} catch (Exception e) {
LOG.error("Failed to set property for unified search.", e);
}
return forumSearch;
}
private String highlightText(String message, String termToHighlight) {
for (String term : termToHighlight.split(" ")) {
message = message.replace(term, "<strong>" + term + "</strong>");
}
return message;
}
private List<ForumSearchResult> removeItemInList(List<ForumSearchResult> listSearchEvent, List<String> forumCanView, List<String> categoryCanView) {
List<ForumSearchResult> tempListSearchEvent = new ArrayList<ForumSearchResult>();
String path = null;
String[] strs;
for (ForumSearchResult forumSearch : listSearchEvent) {
path = forumSearch.getPath();
if (!path.contains(Utils.TOPIC)) {// search category or forum
tempListSearchEvent.add(forumSearch);
continue;
}
strs = path.split("/");
if (categoryCanView.contains(strs[5]) || forumCanView.contains(strs[6])) {
tempListSearchEvent.add(forumSearch);
}
}
return tempListSearchEvent;
}
public List<String> getForumUserCanView(List<String> listOfUser, List<String> listForumIds) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> listForum = new ArrayList<String>();
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder queryString = new StringBuilder();
if(listOfUser == null || listOfUser.isEmpty()) {
listOfUser = new ArrayList<String>();
listOfUser.add(UserProfile.USER_GUEST);
}
// select all forum
// queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_FORUM).append(")[")
// .append("(").append(Utils.buildXpathHasProperty(EXO_VIEWER))
// .append(" or ").append(Utils.buildXpathByUserInfo(EXO_VIEWER, listOfUser)).append(")")
// .append(" or (").append(Utils.buildXpathByUserInfo(EXO_MODERATORS, listOfUser)).append(")")
// .append("]");
// Query query = qm.createQuery(queryString.toString(), Query.XPATH);
queryString.append("SELECT * FROM ").append(EXO_FORUM).append(" WHERE (")
.append(Utils.buildSQLHasProperty(EXO_VIEWER))
.append(" OR ").append(Utils.buildSQLByUserInfo(EXO_VIEWER, listOfUser)).append(")")
.append(" OR (").append(Utils.buildSQLByUserInfo(EXO_MODERATORS, listOfUser)).append(")");
Query query = qm.createQuery(queryString.toString(), Query.SQL);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
Node forumNode = null;
String forumId = null;
while (iter.hasNext()) {
forumNode = iter.nextNode();
forumId = forumNode.getName();
if (listForumIds != null && !listForumIds.isEmpty()) {
if (listForumIds.contains(forumId)) {
listForum.add(forumId);
}
} else {
listForum.add(forumId);
}
}
// If user isn't admin , get all membership of user
if (!isAdminRole(listOfUser.get(0))) {
// Get all category & forum that user can view
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, new ArrayList<String>(), listForum, EXO_USER_PRIVATE);
listForum = mapList.get(Utils.FORUM);
}
return listForum;
}
public List<ForumSearchResult> getAdvancedSearch(ForumEventQuery eventQuery, List<String> listCateIds, List<String> listForumIds){
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>();
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
String path = eventQuery.getPath();
if (path == null || path.length() <= 0) {
path = categoryHome.getPath();
}
eventQuery.setPath(path);
String type = eventQuery.getType();
String queryString = null;
List<String> listOfUser = eventQuery.getListOfUser();
if (eventQuery.getUserPermission() > 0) {
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, EXO_USER_PRIVATE);
listCateIds = mapList.get(Utils.CATEGORY);
listForumIds = mapList.get(Utils.FORUM);
}
if (type.equals(Utils.CATEGORY)) {
queryString = eventQuery.getPathQuery(listCateIds);
} else {
queryString = eventQuery.getPathQuery(listForumIds);
}
Query query = qm.createQuery(queryString, Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
while (iter.hasNext()) {
Node nodeObj = iter.nextNode();
listSearchEvent.add(setPropertyForForumSearch(nodeObj, type));
}
// Note: Query Attachment in post.
if ((type.equals(Utils.POST) || type.equals(Utils.TOPIC)) && !Utils.isEmpty(eventQuery.getKeyValue())) {
boolean isAdmin = false;
if (eventQuery.getUserPermission() == 0)
isAdmin = true;
listSearchEvent.addAll(getSearchByAttachment(categoryHome, eventQuery.getPath(), eventQuery.getKeyValue(), listForumIds, eventQuery.getListOfUser(), isAdmin, type));
}
if (eventQuery.getUserPermission() > 0) {
List<String> categoryCanView = new ArrayList<String>();
List<String> forumCanView = new ArrayList<String>();
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, listCateIds, listForumIds, "@exo:viewer");
categoryCanView = mapList.get(Utils.CATEGORY);
forumCanView.addAll(mapList.get(Utils.FORUM));
forumCanView.addAll(getCachedDataStorage().getForumUserCanView(listOfUser, listForumIds));
if (categoryCanView.size() > 0 || forumCanView.size() > 0)
listSearchEvent = removeItemInList(listSearchEvent, forumCanView, categoryCanView);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()){
LOG.debug("Failed to do advanced search", e);
}
}
return listSearchEvent;
}
private List<ForumSearchResult> getSearchByAttachment(Node categoryHome, String path, String key, List<String> listForumIds, List<String> listOfUser, boolean isAdmin, String type) throws Exception {
List<ForumSearchResult> listSearchEvent = new ArrayList<ForumSearchResult>();
try {
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder strQuery = new StringBuilder();
strQuery.append(JCR_ROOT).append(path).append("//element(*,nt:resource) [");
strQuery.append("(jcr:contains(., '").append(key).append("*'))]");
Query query = qm.createQuery(strQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
boolean isAdd = true;
String type_ = type;
while (iter.hasNext()) {
Node nodeObj = iter.nextNode().getParent().getParent();
if (nodeObj.isNodeType(EXO_POST)) {
if (type == null || type.length() == 0) {
if (nodeObj.getProperty(EXO_IS_FIRST_POST).getBoolean()) {
type_ = Utils.TOPIC;
} else {
type_ = Utils.POST;
}
} else {
if (nodeObj.getProperty(EXO_IS_FIRST_POST).getBoolean()) {
if (!type.equals(Utils.TOPIC))
continue;
} else {
if (type.equals(Utils.TOPIC))
continue;
}
}
// check scoping, private by category.
if (!isAdmin && !listForumIds.isEmpty()) {
String path_ = nodeObj.getPath();
path_ = path_.substring(path_.lastIndexOf(Utils.FORUM), path_.lastIndexOf("/" + Utils.TOPIC));
if (listForumIds.contains(path_))
isAdd = true;
else
isAdd = false;
}
if (isAdd) {
// check post private
List<String> list = Utils.valuesToList(nodeObj.getProperty(EXO_USER_PRIVATE).getValues());
if (!list.get(0).equals(EXO_USER_PRI) && !Utils.isListContentItemList(listOfUser, list))
isAdd = false;
// not is admin
if (isAdd && !isAdmin) {
// not is moderator
list = Utils.valuesToList(nodeObj.getParent().getParent().getProperty(EXO_MODERATORS).getValues());
if (!Utils.hasPermission(listOfUser, list)) {
// can view by topic
list = Utils.valuesToList(nodeObj.getParent().getProperty(EXO_CAN_VIEW).getValues());
if (list != null && list.size() > 0 && !Utils.isEmpty(list.get(0))) {
if (!Utils.hasPermission(listOfUser, list))
isAdd = false;
}
if (isAdd) {
// check by post
Post post = getPost(nodeObj);
if (!post.getIsActiveByTopic() || !post.getIsApproved() || post.getIsHidden() || post.getIsWaiting())
isAdd = false;
}
}
}
}
if (isAdd) {
if (type_.equals(Utils.TOPIC))
nodeObj = nodeObj.getParent();
listSearchEvent.add(setPropertyForForumSearch(nodeObj, type_));
}
}
}
} catch (Exception e) {
LOG.error("Search by attachment has failed", e);
}
return listSearchEvent;
}
private ForumSearchResult setPropertyForForumSearch(Node nodeObj, String type) throws Exception {
ForumSearchResult forumSearch = new ForumSearchResult();
forumSearch.setId(nodeObj.getName());
forumSearch.setPath(nodeObj.getPath());
PropertyReader reader = new PropertyReader(nodeObj);
forumSearch.setName(reader.string(EXO_NAME, ""));
forumSearch.setType(type);
forumSearch.setCreatedDate(reader.date(EXO_CREATED_DATE));
if (type.equals(Utils.FORUM)) {
if (reader.bool(EXO_IS_CLOSED))
forumSearch.setIcon("ForumCloseIcon");
else if (reader.bool(EXO_IS_LOCK))
forumSearch.setIcon("ForumLockedIcon");
else
forumSearch.setIcon("ForumNormalIcon");
} else if (type.equals(Utils.TOPIC)) {
forumSearch.setContent(reader.string(EXO_DESCRIPTION));
if (reader.bool(EXO_IS_CLOSED))
forumSearch.setIcon("HotThreadNoNewClosePost");
else if (reader.bool(EXO_IS_LOCK))
forumSearch.setIcon("HotThreadNoNewLockPost");
else
forumSearch.setIcon("HotThreadNoNewPost");
} else if (type.equals(Utils.CATEGORY)) {
forumSearch.setIcon("CategoryIcon");
} else {
forumSearch.setIcon(reader.string(EXO_ICON, ""));
forumSearch.setContent(reader.string(EXO_MESSAGE));
}
return forumSearch;
}
/**
*
* @param categoryHome
* @param listOfUser
* all group and membership user belong to
* @param listCateIds
* all category visible
* @param listForumIds
* all forum visible
* @return
* @throws Exception
*/
private Map<String, List<String>> getCategoryViewer(Node categoryHome, List<String> listOfUser, List<String> listCateIds, List<String> listForumIds, String property) throws Exception {
Map<String, List<String>> mapList = new HashMap<String, List<String>>();
if (listOfUser == null || listOfUser.isEmpty()) {
listOfUser = new ArrayList<String>();
listOfUser.add(UserProfile.USER_GUEST);
}
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder queryString = new StringBuilder();
queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("/element(*,").append(EXO_FORUM_CATEGORY).append(")[")
.append("(").append(Utils.buildXpathHasProperty(property))
.append(" or ").append(Utils.buildXpathByUserInfo(property, listOfUser)).append(")")
.append(" or (").append(Utils.buildXpathByUserInfo(EXO_MODERATORS, listOfUser)).append(")")
.append("]");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
NodeIterator iter1 = null;
// Check if the result is not all
if (iter.getSize() > 0 && iter.getSize() != categoryHome.getNodes().getSize()) {
String forumId, cateId;
List<String> listForumId = new ArrayList<String>();
List<String> listCateId = new ArrayList<String>();
// Check all category in result.If it can visible then add it to list.
while (iter.hasNext()) {
Node catNode = iter.nextNode();
cateId = catNode.getName();
if (listCateIds != null && !listCateIds.isEmpty()) {
if (listCateIds.contains(cateId)) {
listCateId.add(cateId);
}
} else {
listCateId.add(cateId);
}
// Check all forum in result if it visible then get it
iter1 = catNode.getNodes();
while (iter1.hasNext()) {
Node forumNode = iter1.nextNode();
if (forumNode.isNodeType(EXO_FORUM)) {
forumId = forumNode.getName();
if (listForumIds != null && !listForumIds.isEmpty()) {
if (listForumIds.contains(forumId)) {
listForumId.add(forumId);
}
} else {
listForumId.add(forumId);
}
}
}
}
mapList.put(Utils.FORUM, listForumId);
mapList.put(Utils.CATEGORY, listCateId);
} else if (iter.getSize() == 0) {
if (!property.equals(EXO_VIEWER)) {
listForumIds = new ArrayList<String>();
listForumIds.add("forumId");
mapList.put(Utils.FORUM, listForumIds);
listCateIds = new ArrayList<String>();
listCateIds.add("cateId");
mapList.put(Utils.CATEGORY, listCateIds);
} else {
mapList.put(Utils.FORUM, new ArrayList<String>());
mapList.put(Utils.CATEGORY, new ArrayList<String>());
}
} else {
mapList.put(Utils.FORUM, listForumIds);
mapList.put(Utils.CATEGORY, listCateIds);
}
return mapList;
}
public void addWatch(int watchType, String path, List<String> values, String currentUser) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
if (watchType == -1) {
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer queryString = new StringBuffer();
queryString.append(JCR_ROOT).append(categoryHome.getPath()).append("//*[@exo:id='").append(path).append("']");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iterator = result.getNodes();
path = iterator.nextNode().getPath();
}
if (path.indexOf(categoryHome.getName()) < 0)
path = categoryHome.getPath() + "/" + path;
Node watchingNode = (Node) categoryHome.getSession().getItem(path);
// add watching for node
List<String> listUsers = new ArrayList<String>();
if (watchingNode.isNodeType(EXO_FORUM_WATCHING)) {
if (watchType == 1) {// send email when had changed on category
List<String> listEmail = new ArrayList<String>();
if (watchingNode.hasProperty(EXO_EMAIL_WATCHING))
listEmail.addAll(Utils.valuesToList(watchingNode.getProperty(EXO_EMAIL_WATCHING).getValues()));
if (watchingNode.hasProperty(EXO_USER_WATCHING))
listUsers.addAll(Utils.valuesToList(watchingNode.getProperty(EXO_USER_WATCHING).getValues()));
for (String str : values) {
if (listEmail.contains(str))
continue;
listEmail.add(0, str);
listUsers.add(0, currentUser);
}
watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(listEmail));
watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listUsers));
} else {
watchingNode.setProperty(EXO_RSS_WATCHING, getValueProperty(watchingNode, EXO_RSS_WATCHING, currentUser));
}
} else {
watchingNode.addMixin(EXO_FORUM_WATCHING);
if (watchType == 1) { // send email when had changed on category
for (int i = 0; i < values.size(); i++) {
listUsers.add(currentUser);
}
watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(values));
watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listUsers));
} else { // add RSS watching
watchingNode.setProperty(EXO_RSS_WATCHING, new String[] { currentUser });
}
}
if (watchingNode.isNew()) {
watchingNode.getSession().save();
} else {
watchingNode.save();
}
// if(watchType == -1)addForumSubscription(sProvider, currentUser, watchingNode.getName());
} catch (Exception e) {
LOG.error("Can not add Watch for user: " + currentUser, e);
}
}
public void removeWatch(int watchType, String path, String values) throws Exception {
if (Utils.isEmpty(values))
return;
Node watchingNode = null;
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node categoryHome = getCategoryHome(sProvider);
String string = categoryHome.getPath();
if (path.indexOf(categoryHome.getName()) < 0)
path = string + "/" + path;
try {
watchingNode = (Node) categoryHome.getSession().getItem(path);
List<String> newValues = new ArrayList<String>();
List<String> listNewUsers = new ArrayList<String>();
List<String> userRSS = new ArrayList<String>();
// add watching for node
if (watchingNode.isNodeType(EXO_FORUM_WATCHING)) {
if (watchType == 1) {
String[] emails = new String[] {};
String[] listOldUsers = new String[] {};
String[] listRss = new String[] {};
PropertyReader reader = new PropertyReader(watchingNode);
emails = reader.strings(EXO_EMAIL_WATCHING, new String[] {});
listOldUsers = reader.strings(EXO_USER_WATCHING, new String[] {});
listRss = reader.strings(EXO_RSS_WATCHING, new String[] {});
int n = (listRss.length > listOldUsers.length) ? listRss.length : listOldUsers.length;
for (int i = 0; i < n; i++) {
if (listOldUsers.length > i && !values.contains("/" + emails[i])) {
newValues.add(emails[i]);
listNewUsers.add(listOldUsers[i]);
}
if (listRss.length > i && !values.contains(listRss[i] + "/"))
userRSS.add(listRss[i]);
}
watchingNode.setProperty(EXO_EMAIL_WATCHING, Utils.getStringsInList(newValues));
watchingNode.setProperty(EXO_USER_WATCHING, Utils.getStringsInList(listNewUsers));
watchingNode.setProperty(EXO_RSS_WATCHING, Utils.getStringsInList(userRSS));
if (watchingNode.isNew()) {
watchingNode.getSession().save();
} else {
watchingNode.save();
}
}
}
} catch (Exception e) {
LOG.error("Failed to remove watch.", e);
}
}
public void updateEmailWatch(List<String> listNodeId, String newEmailAdd, String userId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node parentNode = getForumHomeNode(sProvider);
QueryManager qm = parentNode.getSession().getWorkspace().getQueryManager();
StringBuffer queryString = new StringBuffer(JCR_ROOT).append(parentNode.getPath()).append("//element(*,exo:forumWatching)[(");
for (int i = 0; i < listNodeId.size(); i++) {
if (i > 0)
queryString.append(" or ");
queryString.append("@exo:id='").append(listNodeId.get(i)).append("'");
}
queryString.append(")]");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iterator = result.getNodes();
Node watchingNode = null;
List<String> listEmail = null;
List<String> listUsers = null;
while (iterator.hasNext()) {
watchingNode = iterator.nextNode();
PropertyReader reader = new PropertyReader(watchingNode);
listEmail = reader.list(EXO_EMAIL_WATCHING, new ArrayList<String>());
listUsers = reader.list(EXO_USER_WATCHING, new ArrayList<String>());
if (listUsers.contains(userId)) {
for (int i = 0; i < listUsers.size(); i++) {
if (listUsers.get(i).equals(userId)) {
listEmail.set(i, newEmailAdd);
}
}
} else {
listUsers.add(userId);
listEmail.add(newEmailAdd);
}
watchingNode.setProperty(EXO_EMAIL_WATCHING, listEmail.toArray(new String[listEmail.size()]));
watchingNode.setProperty(EXO_USER_WATCHING, listUsers.toArray(new String[listUsers.size()]));
watchingNode.save();
}
} catch (Exception e) {
LOG.error("Failed to update email watch.", e);
}
}
public List<Watch> getWatchByUser(String userId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<Watch> listWatches = new ArrayList<Watch>();
try {
Node categoryHome = getCategoryHome(sProvider);
StringBuffer rootPath = new StringBuffer(categoryHome.getPath());
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer queryString = new StringBuffer();
queryString.append(JCR_ROOT).append(rootPath.toString()).append("//element(*,").append(EXO_FORUM_WATCHING).append(")[(@").append(EXO_USER_WATCHING).append("='").append(userId).append("') or (@").append(EXO_RSS_WATCHING).append("='").append(userId).append("')]");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iterator = result.getNodes();
Watch watch;
Node node;
List<String> users;
List<String> RSSUsers;
String emails[];
String path;
StringBuffer pathName = new StringBuffer();
String typeNode;
PropertyReader reader;
while (iterator.hasNext()) {
node = iterator.nextNode();
reader = new PropertyReader(node);
users = reader.list(EXO_USER_WATCHING, new ArrayList<String>());
emails = reader.strings(EXO_EMAIL_WATCHING, new String[] {});
RSSUsers = reader.list(EXO_RSS_WATCHING, new ArrayList<String>());
rootPath.setLength(0);
rootPath.append(categoryHome.getPath());
path = node.getPath();
pathName.setLength(0);
if (node.isNodeType(Utils.TYPE_CATEGORY)) {
typeNode = Utils.TYPE_CATEGORY;
} else if (node.isNodeType(Utils.TYPE_FORUM)) {
typeNode = Utils.TYPE_FORUM;
} else {
typeNode = Utils.TYPE_TOPIC;
}
for (String str : (path.replace(rootPath.toString() + "/", "")).split("/")) {
rootPath.append("/");
rootPath.append(str);
if (!Utils.isEmpty(pathName.toString())) {
pathName.append(" > ");
}
pathName.append(((Node) categoryHome.getSession().getItem(rootPath.toString())).getProperty(EXO_NAME).getString());
}
watch = new Watch();
watch.setId(node.getName());
watch.setNodePath(path);
watch.setUserId(userId);
watch.setPath(pathName.toString());
watch.setTypeNode(typeNode);
if (users.contains(userId)) {
watch.setEmail(emails[users.indexOf(userId)]);
watch.setIsAddWatchByEmail(true);
} else {
watch.setIsAddWatchByEmail(false);
}
watch.setIsAddWatchByRSS(RSSUsers.contains(userId));
listWatches.add(watch);
}
return listWatches;
} catch (Exception e) {
return listWatches;
}
}
private void sendEmailNotification(List<String> addresses, Message message) throws Exception {
pendingMessagesQueue.add(new SendMessageInfo(addresses, message));
}
public Iterator<SendMessageInfo> getPendingMessages() throws Exception {
Iterator<SendMessageInfo> pending = new ArrayList<SendMessageInfo>(pendingMessagesQueue).iterator();
pendingMessagesQueue.clear();
return pending;
}
public void updateForum(String path) throws Exception {
if (path == null || path.length() <= 0 || path.equals("/" + dataLocator.getForumHomeLocation())) {
path = dataLocator.getForumHomeLocation();
updateForum(path, true);
} else {
updateForum(path, false);
}
}
private void updateForum(String path, boolean isReset) throws Exception {
Map<String, Long> topicMap = new HashMap<String, Long>();
Map<String, Long> postMap = new HashMap<String, Long>();
if (path.indexOf("/") > 0)
path = "/" + path;
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumStatisticNode = getStatisticHome(sProvider).getNode(Locations.FORUM_STATISTIC);
QueryManager qm = forumStatisticNode.getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(JCR_ROOT + path + "//element(*,exo:topic)", Query.XPATH);
QueryResult result = query.execute();
NodeIterator topicIter = result.getNodes();
query = qm.createQuery(JCR_ROOT + path + "//element(*,exo:post)", Query.XPATH);
result = query.execute();
NodeIterator postIter = result.getNodes();
// Update Forum statistic
if (isReset) {
forumStatisticNode.setProperty(EXO_POST_COUNT, postIter.getSize());
forumStatisticNode.setProperty(EXO_TOPIC_COUNT, topicIter.getSize());
} else if (path.indexOf(Utils.FORUM) == path.lastIndexOf(Utils.FORUM)) {
PropertyReader statisticReader = new PropertyReader(forumStatisticNode);
forumStatisticNode.setProperty(EXO_POST_COUNT, statisticReader.l(EXO_POST_COUNT, 0) + postIter.getSize());
forumStatisticNode.setProperty(EXO_TOPIC_COUNT, statisticReader.l(EXO_TOPIC_COUNT, 0) + topicIter.getSize());
}
forumStatisticNode.save();
// put post and topic to maps by user
Node node;
while (topicIter.hasNext()) {
node = topicIter.nextNode();
String owner = node.getProperty(EXO_OWNER).getString();
if (topicMap.containsKey(owner)) {
long l = topicMap.get(owner) + 1;
topicMap.put(owner, l);
} else {
long l = 1;
topicMap.put(owner, l);
}
}
while (postIter.hasNext()) {
node = postIter.nextNode();
String owner = node.getProperty(EXO_OWNER).getString();
if (postMap.containsKey(owner)) {
long l = postMap.get(owner) + 1;
postMap.put(owner, l);
} else {
long l = 1;
postMap.put(owner, l);
}
}
Node profileHome = getUserProfileHome(sProvider);
Node profile;
// update topic to user profile
Iterator<Entry<String, Long>> it = topicMap.entrySet().iterator();
String userId;
Calendar cal = getGreenwichMeanTime();
while (it.hasNext()) {
userId = it.next().getKey();
if (userId.indexOf(Utils.DELETED) < 0) {
if (profileHome.hasNode(userId)) {
profile = profileHome.getNode(userId);
} else {
profile = profileHome.addNode(userId, EXO_FORUM_USER_PROFILE);
profile.setProperty(EXO_USER_ID, userId);
profile.setProperty(EXO_LAST_LOGIN_DATE, cal);
profile.setProperty(EXO_JOINED_DATE, cal);
profile.setProperty(EXO_LAST_POST_DATE, cal);
}
long l = (isReset) ? topicMap.get(userId) : profile.getProperty(EXO_TOTAL_TOPIC).getLong() + topicMap.get(userId);
profile.setProperty(EXO_TOTAL_TOPIC, l);
if (postMap.containsKey(userId)) {
long t = (isReset) ? postMap.get(userId) : profile.getProperty(EXO_TOTAL_POST).getLong() + postMap.get(userId);
profile.setProperty(EXO_TOTAL_POST, t);
profile.setProperty(EXO_LAST_POST_DATE, cal);
postMap.remove(userId);
}
}
}
// update post to user profile
it = postMap.entrySet().iterator();
while (it.hasNext()) {
userId = it.next().getKey();
if (userId.indexOf(Utils.DELETED) < 0) {
if (profileHome.hasNode(userId)) {
profile = profileHome.getNode(userId);
} else {
profile = profileHome.addNode(userId, EXO_FORUM_USER_PROFILE);
profile.setProperty(EXO_USER_ID, userId);
profile.setProperty(EXO_LAST_LOGIN_DATE, cal);
profile.setProperty(EXO_JOINED_DATE, cal);
}
long t = (isReset) ? postMap.get(userId) : profile.getProperty(EXO_TOTAL_POST).getLong() + postMap.get(userId);
profile.setProperty(EXO_TOTAL_POST, t);
profile.setProperty(EXO_LAST_POST_DATE, cal);
}
}
if (profileHome.isNew()) {
profileHome.getSession().save();
} else {
profileHome.save();
}
int t = (profileHome.hasNode(Utils.USER_PROFILE_DELETED)) ? 1 : 0;
forumStatisticNode.setProperty(EXO_MEMBERS_COUNT, profileHome.getNodes().getSize() - t);
forumStatisticNode.save();
} catch (Exception e) {
LOG.error("Failed to update forum", e);
}
}
public SendMessageInfo getMessageInfo(String name) throws Exception {
SendMessageInfo messageInfo = (SendMessageInfo) infoMap.get(name);
infoMap.remove(name);
return messageInfo;
}
private String getPath(String index, String path) throws Exception {
int t = path.lastIndexOf(index);
if (t > 0) {
path = path.substring(t + 1);
}
return path;
}
public List<ForumSearchResult> getJobWattingForModerator(String[] paths){
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<ForumSearchResult> list = new ArrayList<ForumSearchResult>();
try {
Node categoryHome = getCategoryHome(sProvider);
String string = categoryHome.getPath();
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder builder = new StringBuilder();
int l = paths.length;
if (l > 0) {
builder.append(" and (");
for (int i = 0; i < l; i++) {
if (i > 0)
builder.append(" or ");
String str = getPath(("/" + Utils.FORUM), paths[i]);
builder.append("@exo:path='").append(str).append("'");
}
builder.append(")");
}
Query query;
NodeIterator iter;
QueryResult result;
StringBuilder stringBuilder = new StringBuilder(JCR_ROOT).append(string).append("//element(*,").append(EXO_TOPIC).append(")")
.append("[(@").append(EXO_IS_APPROVED).append("='false' or @")
.append(EXO_IS_WAITING).append("='true')").append(builder).append("] order by @exo:modifiedDate descending");
query = qm.createQuery(stringBuilder.toString(), Query.XPATH);
result = query.execute();
iter = result.getNodes();
ForumSearchResult forumSearch;
while (iter.hasNext()) {
forumSearch = new ForumSearchResult();
Node node = iter.nextNode();
forumSearch.setId(node.getName());
forumSearch.setPath(node.getPath());
forumSearch.setType(Utils.TOPIC);
forumSearch.setName(node.getProperty(EXO_NAME).getString());
forumSearch.setContent(node.getProperty(EXO_DESCRIPTION).getString());
forumSearch.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime());
list.add(forumSearch);
}
stringBuilder = new StringBuilder(JCR_ROOT).append(string).append("//element(*,").append(EXO_POST).append(")")
.append("[(@").append(EXO_IS_APPROVED).append("='false' or @").append(EXO_IS_HIDDEN)
.append("='true' or @").append(EXO_IS_WAITING).append("='true')").append(builder).append("] order by @exo:modifiedDate descending");
query = qm.createQuery(stringBuilder.toString(), Query.XPATH);
result = query.execute();
iter = result.getNodes();
while (iter.hasNext()) {
forumSearch = new ForumSearchResult();
Node node = iter.nextNode();
forumSearch.setId(node.getName());
forumSearch.setPath(node.getPath());
forumSearch.setType(Utils.POST);
forumSearch.setName(node.getProperty(EXO_NAME).getString());
forumSearch.setContent(node.getProperty(EXO_MESSAGE).getString());
forumSearch.setCreatedDate(node.getProperty(EXO_CREATED_DATE).getDate().getTime());
list.add(forumSearch);
}
} catch (Exception e) {
LOG.error("Failed to get waiting jobs for moderator", e);
}
return list;
}
public int getJobWattingForModeratorByUser(String userId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
int job = 0;
Node newProfileNode = getUserProfileHome(sProvider).getNode(userId);
long t;// = 3
if (isAdminRole(userId)) {
t = 0;
} else {
t = newProfileNode.getProperty(EXO_USER_ROLE).getLong();
}
if (t < 2) {
try {
job = (int) newProfileNode.getProperty(EXO_JOB_WATTING_FOR_MODERATOR).getLong();
} catch (Exception e) {
job = 0;
}
}
return job;
}
private int getTotalJobWaitingForModerator(Session session, String userId) throws Exception {
int totalJob = 0;
try {
Node newProfileNode = session.getRootNode().getNode(dataLocator.getUserProfilesLocation()).getNode(userId);
long t;// = 3;
if (isAdminRole(userId)) {
t = 0;
} else {
t = newProfileNode.getProperty(EXO_USER_ROLE).getLong();
}
if (t < 2) {
Node categoryHome = session.getRootNode().getNode(dataLocator.getForumCategoriesLocation());
String string = categoryHome.getPath();
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer buffer = new StringBuffer();
if (t > 0) {
String[] paths = Utils.valuesToArray(newProfileNode.getProperty(EXO_MODERATE_FORUMS).getValues());
int l = paths.length;
if (l > 0) {
buffer.append(" and (");
for (int i = 0; i < l; i++) {
if (i > 0)
buffer.append(" or ");
String str = getPath(("/" + Utils.FORUM), paths[i]);
buffer.append("@exo:path='").append(str).append("'");
}
buffer.append(")");
}
}
StringBuffer stringBuffer = new StringBuffer(JCR_ROOT).append(string).append("//element(*,").append(EXO_TOPIC).append(")")
.append("[(@").append(EXO_IS_APPROVED).append("='false' or @")
.append(EXO_IS_WAITING).append("='true')").append(buffer).append("]");
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
totalJob = (int) iter.getSize();
stringBuffer = new StringBuffer(JCR_ROOT).append(string).append("//element(*,").append(EXO_POST).append(")")
.append("[(@").append(EXO_IS_APPROVED).append("='false' or @").append(EXO_IS_HIDDEN)
.append("='true' or @").append(EXO_IS_WAITING).append("='true')").append(buffer).append("]");
query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
result = query.execute();
iter = result.getNodes();
totalJob = totalJob + (int) iter.getSize();
newProfileNode.setProperty(EXO_JOB_WATTING_FOR_MODERATOR, totalJob);
newProfileNode.save();
}
} catch (Exception e) {
LOG.error("Failed to get total job watting for moderator", e);
}
return totalJob;
}
private void getTotalJobWatting(SessionProvider sProvider, Set<String> userIds) {
try {
ContinuationService continuation = CommonUtils.getComponent(ContinuationService.class);
if (continuation != null) {
Set<String> set = new HashSet<String>(ForumServiceUtils.getUserPermission(userIds.toArray(new String[userIds.size()])));
set.addAll(getAllAdministrator(sProvider));
JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl();
Category cat = new Category();
for (String userId : set) {
if (Utils.isEmpty(userId) || userId.indexOf(CommonUtils.SLASH) > 0 || userId.indexOf(CommonUtils.COLON) > 0) continue;
int job = getTotalJobWaitingForModerator(getForumHomeNode(sProvider).getSession(), userId);
if (job >= 0) {
cat.setCategoryName(String.valueOf(job));
JsonValue json = generatorImpl.createJsonObject(cat);
continuation.sendMessage(userId, "/eXo/Application/Forum/messages", json, cat.toString());
}
}
}
} catch (Exception e) {
LOG.error("Failed to get total job waiting for moderator", e);
}
}
public void sendNotificationMessage(ForumPrivateMessage message) {
try {
if (message != null) {
ContinuationService continuation = CommonUtils.getComponent(ContinuationService.class);
String[] sendTo = message.getSendTo().replaceAll(";", ",").split(",");
String from = message.getFrom();
message.setFrom(getScreenName(from));
JsonGeneratorImpl generatorImpl = new JsonGeneratorImpl();
JsonValue json = generatorImpl.createJsonObject(message);
for (int i = 0; i < sendTo.length; i++) {
String to = sendTo[i].trim();
if (to.equals(from)) {
continue;
}
continuation.sendMessage(to, "/eXo/Application/Forum/NotificationMessage", json, message.toString());
}
}
} catch (Exception e) {
LOG.error("Failed to send notification message:" + e.getMessage());
}
}
public NodeIterator search(String queryString) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(queryString, Query.XPATH);
QueryResult result = query.execute();
return result.getNodes();
} catch (Exception e) {
LOG.error("Failed to search", e);
}
return null;
}
public void evaluateActiveUsers(String strQuery){
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
String path = getUserProfileHome(sProvider).getPath();
StringBuilder stringBuilder = new StringBuilder();
if (strQuery == null || strQuery.length() == 0) {
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTimeInMillis(calendar.getTimeInMillis() - 864000000);
stringBuilder.append(JCR_ROOT).append(path).append("//element(*,").append(EXO_FORUM_USER_PROFILE).append(")[").append("@exo:lastPostDate >= xs:dateTime('").append(ISO8601.format(calendar)).append("')]");
} else {
stringBuilder.append(JCR_ROOT).append(path).append(strQuery);
}
QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(stringBuilder.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
Node statisticHome = getStatisticHome(sProvider);
if (statisticHome.hasNode(Locations.FORUM_STATISTIC)) {
statisticHome.getNode(Locations.FORUM_STATISTIC).setProperty(EXO_ACTIVE_USERS, iter.getSize());
statisticHome.save();
} else {
ForumStatistic forumStatistic = new ForumStatistic();
forumStatistic.setActiveUsers(iter.getSize());
saveForumStatistic(forumStatistic);
}
} catch (Exception e) {
LOG.error("Failed to evaluate active users", e);
} finally {
sProvider.close();
}
}
protected List<File> createCategoryFiles(List<String> objectIds, SessionProvider sessionProvider) throws Exception {
List<File> listFiles = new ArrayList<File>();
ByteArrayOutputStream outputStream = null;
Node categoryHome = getCategoryHome(sessionProvider);
Node cateNode = null;
for (String categoryId : objectIds) {
try {
cateNode = categoryHome.getNode(categoryId);
outputStream = new ByteArrayOutputStream();
Calendar date = new GregorianCalendar();
categoryHome.getSession().exportSystemView(cateNode.getPath(), outputStream, false, false);
listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", "Category", date.getTime(), cateNode.getName()));
} finally {
outputStream.close();
}
}
return listFiles;
}
protected List<File> createForumFiles(String categoryId, List<String> objectIds, SessionProvider sessionProvider) throws Exception {
List<File> listFiles = new ArrayList<File>();
List<Forum> forums = getCachedDataStorage().getForums(new ForumFilter(categoryId, true));
for (Forum forum : forums) {
if (objectIds.size() > 0 && !objectIds.contains(forum.getId()))
continue;
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
Calendar calendar = GregorianCalendar.getInstance();
getCategoryHome(sessionProvider).getSession().exportSystemView(forum.getPath(), outputStream, false, false);
listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", "Forum", calendar.getTime(), forum.getId()));
} finally {
outputStream.close();
}
}
return listFiles;
}
protected List<File> createFilesFromNode(Node node, String type) throws Exception {
List<File> listFiles = new ArrayList<File>();
if (node != null) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
Calendar calendar = GregorianCalendar.getInstance();
node.getSession().exportSystemView(node.getPath(), outputStream, false, false);
listFiles.add(CommonUtils.getXMLFile(outputStream, "eXo Knowledge Suite - Forum", type, calendar.getTime(), node.getName()));
} finally {
outputStream.close();
}
}
return listFiles;
}
protected List<File> createAllForumFiles(SessionProvider sessionProvider) throws Exception {
List<File> listFiles = new ArrayList<File>();
/*
* // Create Statistic file listFiles.addAll(createFilesFromNodeIter(categoryHome, null, getStatisticHome(sessionProvider), ""));
*/
// Create Administration file
listFiles.addAll(createFilesFromNode(getAdminHome(sessionProvider), Locations.ADMINISTRATION_HOME));
// Create UserProfile files
listFiles.addAll(createFilesFromNode(getUserProfileHome(sessionProvider), Locations.USER_PROFILE_HOME));
// create tag files
listFiles.addAll(createFilesFromNode(getTagHome(sessionProvider), Locations.TAG_HOME));
// Create BBCode file
listFiles.addAll(createFilesFromNode(getBBCodesHome(sessionProvider), Locations.BBCODE_HOME));
// Create BanIP file
listFiles.addAll(createFilesFromNode(getBanIPHome(sessionProvider), Locations.BANIP_HOME));
// Create category home file
listFiles.addAll(createFilesFromNode(getCategoryHome(sessionProvider), Locations.FORUM_CATEGORIES_HOME));
return listFiles;
}
public Object exportXML(String categoryId, String forumId, List<String> objectIds, String nodePath, ByteArrayOutputStream bos, boolean isExportAll) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
List<File> listFiles = new ArrayList<File>();
if (!isExportAll) {
if (categoryId != null) {
if (Utils.isEmpty(forumId)) {
listFiles.addAll(createForumFiles(categoryId, objectIds, sProvider));
} else {
Node categoryHome = getCategoryHome(sProvider);
categoryHome.getSession().exportSystemView(nodePath, bos, false, false);
return null;
}
} else {
listFiles.addAll(createCategoryFiles(objectIds, sProvider));
}
} else {
listFiles.addAll(createAllForumFiles(sProvider));
}
ZipOutputStream zipOutputStream = null;
try {
zipOutputStream = new ZipOutputStream(new FileOutputStream("exportCategory.zip"));
int byteReads;
byte[] buffer = new byte[4096]; // Create a buffer for copying
FileInputStream inputStream = null;
ZipEntry zipEntry = null;
for (File f : listFiles) {
inputStream = new FileInputStream(f);
try {
zipEntry = new ZipEntry(f.getPath());
zipOutputStream.putNextEntry(zipEntry);
while ((byteReads = inputStream.read(buffer)) != -1)
zipOutputStream.write(buffer, 0, byteReads);
} finally {
inputStream.close();
}
}
} finally {
zipOutputStream.close();
}
File file = new File("exportCategory.zip");
for (File f : listFiles)
f.deleteOnExit();
return file;
} catch (Exception e) {
return null;
}
}
public void importXML(String nodePath, ByteArrayInputStream bis, int typeImport) throws Exception {
String nodeName = "";
byte[] bdata = new byte[bis.available()];
bis.read(bdata);
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
//disallow doctype declaration in order to prevent xxe attack
docBuilderFactory.setFeature(DOCTYPE_DECLARATION_DISALLOW,true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
ByteArrayInputStream is = new ByteArrayInputStream(bdata);
try {
Document doc = docBuilder.parse(is);
doc.getDocumentElement().normalize();
String typeNodeExport = ((org.w3c.dom.Node) doc.getFirstChild().getChildNodes().item(0).getChildNodes().item(0)).getTextContent();
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> patchNodeImport = new ArrayList<String>();
Node forumHome = getForumHomeNode(sProvider);
is = new ByteArrayInputStream(bdata);
if (!typeNodeExport.equals(EXO_FORUM_CATEGORY) && !typeNodeExport.equals(EXO_FORUM)) {
// All nodes when import need reset childnode
if (typeNodeExport.equals(EXO_CATEGORY_HOME)) {
nodePath = getCategoryHome(sProvider).getPath();
Node categoryHome = getCategoryHome(sProvider);
nodeName = "CategoryHome";
addDataFromXML(categoryHome, nodePath, sProvider, is, nodeName);
} else if (typeNodeExport.equals(EXO_USER_PROFILE_HOME)) {
Node userProfile = getUserProfileHome(sProvider);
nodeName = "UserProfileHome";
nodePath = getUserProfileHome(sProvider).getPath();
addDataFromXML(userProfile, nodePath, sProvider, is, nodeName);
} else if (typeNodeExport.equals(EXO_TAG_HOME)) {
Node tagHome = getTagHome(sProvider);
nodePath = getTagHome(sProvider).getPath();
nodeName = "TagHome";
addDataFromXML(tagHome, nodePath, sProvider, is, nodeName);
} else if (typeNodeExport.equals(EXO_FORUM_BB_CODE_HOME)) {
nodePath = dataLocator.getBBCodesLocation();
Node bbcodeNode = getBBCodesHome(sProvider);
nodeName = "forumBBCode";
addDataFromXML(bbcodeNode, nodePath, sProvider, is, nodeName);
}
// Node import but don't need reset childnodes
else if (typeNodeExport.equals(EXO_ADMINISTRATION_HOME)) {
nodePath = getForumSystemHome(sProvider).getPath();
Node node = getAdminHome(sProvider);
node.remove();
getForumSystemHome(sProvider).save();
typeImport = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING;
Session session = forumHome.getSession();
session.importXML(nodePath, is, typeImport);
session.save();
} else if (typeNodeExport.equals(EXO_BAN_IP_HOME)) {
nodePath = getForumSystemHome(sProvider).getPath();
Node node = getBanIPHome(sProvider);
node.remove();
getForumSystemHome(sProvider).save();
typeImport = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING;
Session session = forumHome.getSession();
session.importXML(nodePath, is, typeImport);
session.save();
} else {
throw new RuntimeException("unknown type of node to export :" + typeNodeExport);
}
} else {
if (typeNodeExport.equals(EXO_FORUM_CATEGORY)) {
// Check if import forum but the data import have structure of a category --> Error
if (nodePath.split("/").length == 6) {
throw new ConstraintViolationException();
}
nodePath = getCategoryHome(sProvider).getPath();
}
Session session = forumHome.getSession();
NodeIterator iter = ((Node) session.getItem(nodePath)).getNodes();
while (iter.hasNext()) {
patchNodeImport.add(iter.nextNode().getName());
}
session.importXML(nodePath, is, typeImport);
session.save();
NodeIterator newIter = ((Node) session.getItem(nodePath)).getNodes();
while (newIter.hasNext()) {
Node node = newIter.nextNode();
if (patchNodeImport.contains(node.getName()))
patchNodeImport.remove(node.getName());
else
patchNodeImport.add(node.getName());
}
}
// update forum statistic and profile of owner post.
if (typeNodeExport.equals(EXO_FORUM_CATEGORY) || typeNodeExport.equals(EXO_FORUM)) {
for (String string : patchNodeImport) {
updateForum(nodePath + "/" + string, false);
}
} else if (typeNodeExport.equals(EXO_CATEGORY_HOME)) {
updateForum(null);
}
} finally {
is.close();
}
}
private void addDataFromXML(Node sourceNode, String nodePath, SessionProvider sessionProvider, InputStream is, String nodeName) throws Exception {
Node forumHomeNode = getForumHomeNode(sessionProvider);
Session session = forumHomeNode.getSession();
Node tempNode = forumHomeNode.getParent().addNode("DataTemp");
// Add child node of DataTemp
session.importXML(tempNode.getPath(), is, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
session.save();
// Node store data from XML file.
Node importNode = tempNode.getNode(nodeName);
try {
copyFullNodes(sourceNode, importNode, session);
} finally {
tempNode.remove();
forumHomeNode.getParent().save();
}
}
private void copyFullNodes(Node sourceNode, Node importNode, Session session) throws Exception {
// Check if importNode have different child than sourceNode then add it.
NodeIterator sourceIter = sourceNode.getNodes();
NodeIterator importIter = importNode.getNodes();
Node srcTemp = null;
Node importTemp = null;
boolean flag = false;
while (importIter.hasNext()) {
flag = true;
importTemp = importIter.nextNode();
while (sourceIter.hasNext()) {
srcTemp = sourceIter.nextNode();
if (importTemp.getName().equals(srcTemp.getName())) {
copyFullNodes(srcTemp, importTemp, session);
flag = false;
break;
}
}
if (flag) {
String path = sourceNode.getPath() + "/" + importTemp.getName();
try {
session.getWorkspace().copy(importTemp.getPath(), path);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug(path + " or " + importTemp.getPath() + " does not exist: " + e.getMessage() + "\n" + e.getCause());
}
}
}
}
}
public void updateTopicAccess(String userId, String topicId) {
if (updatingRead.containsKey(userId)) {
updatingRead.get(userId).add(topicId);
} else {
List<String> value = new ArrayList<String>();
value.add(topicId);
updatingRead.put(userId, value);
}
}
public void writeReads() {
//
Map<String, List<String>> map = updatingRead;
updatingRead = new ConcurrentHashMap<String, List<String>>();
//
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Node userHome = getUserProfileHome(sProvider);
long currentTime = getGreenwichMeanTime().getTimeInMillis();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
try {
if (!userHome.hasNode(entry.getKey())) {
return;
}
//
Node profile = userHome.getNode(entry.getKey());
List<String> values = new PropertyReader(profile).list(EXO_READ_TOPIC, new ArrayList<String>());
//
for (String topicId : entry.getValue()) {
//
int i = 0;
boolean isUpdated = false;
for (String vl : values) {
if (vl.indexOf(topicId) == 0) {
values.set(i, topicId + ":" + currentTime);
isUpdated = true;
break;
}
i++;
}
//
if (!isUpdated) {
values.add(topicId + ":" + currentTime);
}
//
profile.setProperty(EXO_READ_TOPIC, values.toArray(new String[values.size()]));
}
} catch (Exception e) {
logDebug(String.format("Failed to update user %s acess for topics %s", entry.getKey(), entry.getValue().toString()), e);
}
}
userHome.getSession().save();
} catch (Exception e) {
logDebug("Writing reads topic is unsuccessfully.", e);
} finally {
sProvider.close();
}
}
public void updateForumAccess(String userId, String forumId){
SessionProvider sysSession = CommonUtils.createSystemProvider();
try {
Node profile = getUserProfileHome(sysSession).getNode(userId);
List<String> values = new ArrayList<String>();
if (profile.hasProperty(EXO_READ_FORUM)) {
values = Utils.valuesToList(profile.getProperty(EXO_READ_FORUM).getValues());
}
int i = 0;
boolean isUpdated = false;
for (String vl : values) {
if (vl.indexOf(forumId) == 0) {
values.set(i, forumId + ":" + getGreenwichMeanTime().getTimeInMillis());
isUpdated = true;
break;
}
i++;
}
if (!isUpdated) {
values.add(forumId + ":" + getGreenwichMeanTime().getTimeInMillis());
}
if (values.size() == 2 && Utils.isEmpty(values.get(0)))
values.remove(0);
profile.setProperty(EXO_READ_FORUM, values.toArray(new String[values.size()]));
profile.save();
} catch (Exception e) {
LOG.warn(String.format("Failed to update user %s acess for forum %s", userId, forumId));
}
}
public List<String> getBookmarks(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node profile = getUserProfileHome(sProvider).getNode(userName);
if (profile.hasProperty(EXO_BOOKMARK)) {
return Utils.valuesToList(profile.getProperty(EXO_BOOKMARK).getValues());
}
return new ArrayList<String>();
}
public List<String> getBanList() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node banNode = getForumBanNode(sProvider);
if (banNode.hasProperty(EXO_IPS))
return Utils.valuesToList(banNode.getProperty(EXO_IPS).getValues());
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get ban list", e);
}
}
return new ArrayList<String>();
}
public boolean addBanIP(String ip) throws Exception {
List<String> ips = getBanList();
if (ips.contains(ip))
return false;
ips.add(ip);
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node banNode = getForumBanNode(sProvider);
banNode.setProperty(EXO_IPS, ips.toArray(new String[ips.size()]));
if (banNode.isNew()) {
banNode.getSession().save();
} else {
banNode.save();
}
return true;
} catch (Exception e) {
LOG.error("Failed to add ban ip: " + ip, e);
}
return false;
}
public void removeBan(String ip) throws Exception {
List<String> ips = getBanList();
if (ips.contains(ip)) {
ips.remove(ip);
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node banNode = getForumBanNode(sProvider);
banNode.setProperty(EXO_IPS, Utils.getStringsInList(ips));
banNode.save();
} catch (Exception e) {
LOG.error("Failed to remove ban, ip: " + ip, e);
}
}
}
public List<String> getForumBanList(String forumId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> list = new ArrayList<String>();
try {
if (forumId.indexOf(".") > 0)
forumId = StringUtils.replace(forumId, ".", "/");
Node forumNode = getCategoryHome(sProvider).getNode(forumId);
if (forumNode.hasProperty(EXO_BAN_I_PS))
list.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues()));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get forum ban list.", e);
}
}
return list;
}
public boolean addBanIPForum(String ip, String forumId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> ips = new ArrayList<String>();
try {
Node forumNode = getCategoryHome(sProvider).getNode(forumId);
if (forumNode.hasProperty(EXO_BAN_I_PS))
ips.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues()));
if (ips.contains(ip))
return false;
ips.add(ip);
forumNode.setProperty(EXO_BAN_I_PS, Utils.getStringsInList(ips));
if (forumNode.isNew()) {
forumNode.getSession().save();
} else {
forumNode.save();
}
return true;
} catch (Exception e) {
LOG.error("Failed to add ban ip forum.", e);
}
return false;
}
public void removeBanIPForum(String ip, String forumId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<String> ips = new ArrayList<String>();
try {
Node forumNode = getCategoryHome(sProvider).getNode(forumId);
if (forumNode.hasProperty(EXO_BAN_I_PS))
ips.addAll(Utils.valuesToList(forumNode.getProperty(EXO_BAN_I_PS).getValues()));
if (ips.contains(ip)) {
ips.remove(ip);
forumNode.setProperty(EXO_BAN_I_PS, Utils.getStringsInList(ips));
if (forumNode.isNew()) {
forumNode.getSession().save();
} else {
forumNode.save();
}
}
} catch (Exception e) {
LOG.error("Failed to remove ban IP from forum", e);
}
}
private List<String> getAllAdministrator(SessionProvider sProvider) throws Exception {
QueryManager qm = getForumHomeNode(sProvider).getSession().getWorkspace().getQueryManager();
StringBuilder pathQuery = new StringBuilder();
pathQuery.append(JCR_ROOT).append(getUserProfileHome(sProvider).getPath()).append("//element(*,").append(EXO_FORUM_USER_PROFILE).append(")[@exo:userRole=0]");
Query query = qm.createQuery(pathQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
List<String> list = new ArrayList<String>();
while (iter.hasNext()) {
Node userNode = iter.nextNode();
list.add(userNode.getName());
}
return list;
}
public void updateStatisticCounts(long topicCount, long postCount) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
ReentrantLock lock = this.lock;
try {
lock.lock();
Node forumStatisticNode = getForumStatisticsNode(sProvider);
PropertyReader reader = new PropertyReader(forumStatisticNode);
if (topicCount != 0) {
long count = reader.l(EXO_TOPIC_COUNT);
if (count < 0)
count = 0;
forumStatisticNode.setProperty(EXO_TOPIC_COUNT, count + topicCount);
}
if (postCount != 0) {
long count = reader.l(EXO_POST_COUNT);
if (count < 0)
count = 0;
forumStatisticNode.setProperty(EXO_POST_COUNT, count + postCount);
}
forumStatisticNode.save();
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to update statistic counts", e);
}
} finally {
lock.unlock();
sProvider.close();
}
}
private PruneSetting getPruneSetting(Node prunNode) throws Exception {
PruneSetting pruneSetting = new PruneSetting();
pruneSetting.setId(prunNode.getName());
pruneSetting.setForumPath(prunNode.getParent().getPath());
pruneSetting.setActive(prunNode.getProperty(EXO_IS_ACTIVE).getBoolean());
pruneSetting.setCategoryName(prunNode.getParent().getParent().getProperty(EXO_NAME).getString());
pruneSetting.setForumName(prunNode.getParent().getProperty(EXO_NAME).getString());
pruneSetting.setInActiveDay(prunNode.getProperty(EXO_IN_ACTIVE_DAY).getLong());
pruneSetting.setPeriodTime(prunNode.getProperty(EXO_PERIOD_TIME).getLong());
if (prunNode.hasProperty(EXO_LAST_RUN_DATE))
pruneSetting.setLastRunDate(prunNode.getProperty(EXO_LAST_RUN_DATE).getDate().getTime());
return pruneSetting;
}
public PruneSetting getPruneSetting(String forumPath) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
PruneSetting pruneSetting = new PruneSetting();
try {
Node forumNode = (Node) getCategoryHome(sProvider).getSession().getItem(forumPath);
pruneSetting = getPruneSetting(forumNode.getNode(Utils.PRUNESETTING));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get Prune Settings: " + e.getMessage() + "\n" + e.getCause());
}
}
return pruneSetting;
}
public List<PruneSetting> getAllPruneSetting() throws Exception {
List<PruneSetting> prunList = new ArrayList<PruneSetting>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
NodeIterator iter = getNodeIteratorAutoPruneSetting(sProvider, false);
while (iter.hasNext()) {
Node prunNode = iter.nextNode();
prunList.add(getPruneSetting(prunNode));
}
return prunList;
}
public void savePruneSetting(PruneSetting pruneSetting) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
String path = pruneSetting.getForumPath();
Node forumNode = (Node) getForumHomeNode(sProvider).getSession().getItem(path);
Node pruneNode;
try {
pruneNode = forumNode.getNode(Utils.PRUNESETTING);
} catch (Exception e) {
pruneNode = forumNode.addNode(Utils.PRUNESETTING, EXO_PRUNE_SETTING);
pruneNode.setProperty(EXO_ID, pruneSetting.getId());
}
pruneNode.setProperty(EXO_IN_ACTIVE_DAY, pruneSetting.getInActiveDay());
pruneNode.setProperty(EXO_PERIOD_TIME, pruneSetting.getPeriodTime());
pruneNode.setProperty(EXO_IS_ACTIVE, pruneSetting.isActive());
if (pruneSetting.getLastRunDate() != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(pruneSetting.getLastRunDate());
pruneNode.setProperty(EXO_LAST_RUN_DATE, calendar);
}
if (pruneNode.isNew())
forumNode.getSession().save();
else
forumNode.save();
try {
addOrRemoveSchedule(pruneSetting);
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to add or remove prune jobs", e);
}
}
} catch (Exception e) {
LOG.error("Failed to save prune setting.", e);
}
}
private void addOrRemoveSchedule(PruneSetting pSetting) throws Exception{
Calendar cal = new GregorianCalendar();
PeriodInfo periodInfo = new PeriodInfo(cal.getTime(), null, -1, (pSetting.getPeriodTime() * 86400000)); // pSetting.getPeriodTime() return value
JobInfo info = new JobInfo(pSetting.getId(), KNOWLEDGE_SUITE_FORUM_JOBS, AutoPruneJob.class);
ExoContainer container = ExoContainerContext.getCurrentContainer();
JobSchedulerService schedulerService = (JobSchedulerService) container.getComponentInstanceOfType(JobSchedulerService.class);
schedulerService.removeJob(info);
if (pSetting.isActive()) {
info = new JobInfo(pSetting.getId(), KNOWLEDGE_SUITE_FORUM_JOBS, AutoPruneJob.class);
info.setDescription(pSetting.getForumPath());
RepositoryService repositoryService = (RepositoryService) ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(RepositoryService.class);
String repoName = repositoryService.getCurrentRepository().getConfiguration().getName();
JobDataMap jdatamap = new JobDataMap();
jdatamap.put(Utils.CACHE_REPO_NAME, repoName);
schedulerService.addPeriodJob(info, periodInfo, jdatamap);
if (LOG.isInfoEnabled()) {
LOG.info("\n\nActivated " + info.getJobName());
}
}
}
public void runPrune(String forumPath) throws Exception {
runPrune(getPruneSetting(forumPath));
}
public void runPrune(PruneSetting pSetting) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node forumNode = (Node) getForumHomeNode(sProvider).getSession().getItem(pSetting.getForumPath());
NodeIterator iter = getIteratorPrune(sProvider, pSetting);
List<String> topicPruned = new ArrayList<String>();
while (iter.hasNext()) {
Node topic = iter.nextNode();
topic.setProperty(EXO_IS_ACTIVE, false);
topic.save();
topicPruned.add(topic.getPath());
try {
Node forumN = topic.getParent();
if (new PropertyReader(forumN).string(EXO_LAST_TOPIC_PATH, "").indexOf(topic.getName()) >= 0) {
queryLastTopic(sProvider, forumN.getPath());
}
} catch (Exception e) {
LOG.warn("Failed to save new value last post date in forum", e);
}
}
// update last run for prune setting
Node setting = forumNode.getNode(pSetting.getId());
setting.setProperty(EXO_LAST_RUN_DATE, getGreenwichMeanTime());
forumNode.save();
//
DataStorage storage = getCachedDataStorage();
if (storage instanceof CachedDataStorage) {
for (String topicPath : topicPruned) {
((CachedDataStorage) storage).clearTopicCache(storage.getTopicByPath(topicPath, false));
}
}
} catch (Exception e) {
LOG.error("Failed to run prune", e);
}
}
private NodeIterator getIteratorPrune(SessionProvider sProvider, PruneSetting pSetting) throws Exception {
Node forumHome = getForumHomeNode(sProvider);
Node forumNode = (Node) forumHome.getSession().getItem(pSetting.getForumPath());
Calendar newDate = getGreenwichMeanTime();
newDate.setTimeInMillis(newDate.getTimeInMillis() - pSetting.getInActiveDay() * 86400000);
QueryManager qm = forumHome.getSession().getWorkspace().getQueryManager();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(JCR_ROOT).append(forumNode.getPath()).append("/element(*,").append(EXO_TOPIC).append(")[ @").append(EXO_IS_ACTIVE).append("='true' and @").append(EXO_LAST_POST_DATE).append(" <= xs:dateTime('").append(ISO8601.format(newDate)).append("')]");
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
QueryResult result = query.execute();
return result.getNodes();
}
public long checkPrune(PruneSetting pSetting) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
return getIteratorPrune(sProvider, pSetting).getSize();
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to check prune", e);
}
}
return 0;
}
public InputStream createForumRss(String objectId, String link) throws Exception {
List<SyndEntry> entries = new ArrayList<SyndEntry>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node node_ = null;
if (objectId.indexOf(Utils.CATEGORY) == 0) {
node_ = getNodeById(sProvider, objectId, Utils.CATEGORY);
entries.addAll(categoryUpdated(node_));
} else if (objectId.indexOf(Utils.FORUM) == 0) {
node_ = getNodeById(sProvider, objectId, Utils.FORUM);
entries.addAll(forumUpdated(node_));
} else {
node_ = getNodeById(sProvider, objectId, Utils.TOPIC);
String link_ = node_.getProperty(EXO_LINK).getString();
link = Utils.isEmpty(link_) ? link : link_;
entries.addAll(topicUpdated(node_));
}
SyndFeed feed = createNewFeed(node_, link);
feed.setEntries(entries);
SyndFeedOutput output = new SyndFeedOutput();
String s = output.outputString(feed);
s = StringUtils.replace(s, "&", "&");
s = s.replaceAll("<", "<").replaceAll(">", ">");
s = StringUtils.replace(s, "ST[CDATA[", "<![CDATA[");
s = StringUtils.replace(s, "END]]", "]]>");
return new ByteArrayInputStream(s.getBytes());
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to create forum rss", e);
}
}
return null;
}
private List<SyndEntry> categoryUpdated(Node cateNode) throws Exception {
List<SyndEntry> entries = new ArrayList<SyndEntry>();
NodeIterator iterator = cateNode.getNodes();
while (iterator.hasNext()) {
Node node = iterator.nextNode();
if (node.isNodeType(EXO_FORUM) && !node.getProperty(EXO_IS_CLOSED).getBoolean()) {
entries.addAll(forumUpdated(node));
}
}
return entries;
}
private List<SyndEntry> forumUpdated(Node forumNode) throws Exception {
List<SyndEntry> entries = new ArrayList<SyndEntry>();
try {
QueryManager qm = forumNode.getSession().getWorkspace().getQueryManager();
StringBuilder queryString = new StringBuilder(JCR_ROOT).append(forumNode.getPath()).append("//element(*,exo:topic)[@exo:isWaiting='false' and @exo:isActive='true' and @exo:isClosed='false' and (not(@exo:canView) or @exo:canView='' or @exo:canView=' ')]").append(" order by @exo:isSticky descending, @exo:lastPostDate descending");
Query query = qm.createQuery(queryString.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
while (iter.hasNext()) {
entries.addAll(topicUpdated(iter.nextNode()));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to update syndEntry by forum.", e);
}
}
return entries;
}
private List<SyndEntry> topicUpdated(Node topicNode) {
List<SyndEntry> entries = new ArrayList<SyndEntry>();
try {
Node forumNode = topicNode.getParent();
Node categoryNode = forumNode.getParent();
boolean categoryHasRestrictedAudience = (hasProperty(categoryNode, EXO_VIEWER));
boolean forumHasRestrictedAudience = (hasProperty(forumNode, EXO_VIEWER));
String topicName = topicNode.getName();
if (categoryHasRestrictedAudience || forumHasRestrictedAudience) {
if (LOG.isDebugEnabled()) {
LOG.debug("Post" + topicName + " was not added to feed because category or forum has restricted audience");
}
return null;
}
// update posts in topic
QueryManager qm = topicNode.getSession().getWorkspace().getQueryManager();
StringBuffer stringBuffer = new StringBuffer(JCR_ROOT)
.append(topicNode.getPath()).append("//element(*,").append(EXO_POST).append(")")
.append(Utils.getPathQuery("true", "false", "false", EXO_USER_PRI))
.append(" order by @exo:createdDate ascending");
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
Node postNode = null;
while (iter.hasNext()) {
postNode = iter.nextNode();
try {
entries.add(postUpdated(postNode));
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to generate feed for post " + postNode.getPath(), e);
}
}
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to update sundEntry by topic.", e);
}
}
return entries;
}
private SyndEntry postUpdated(Node postNode) throws Exception {
Node topicNode = postNode.getParent();
String postName = postNode.getName();
PropertyReader post = new PropertyReader(postNode);
boolean notApproved = !post.bool(EXO_IS_APPROVED);
boolean isPrivatePost = !post.list(EXO_USER_PRIVATE, new ArrayList<String>()).contains(EXO_USER_PRI);
boolean topicHasLimitedViewers = hasProperty(topicNode, EXO_CAN_VIEW);
if ((notApproved) || isPrivatePost || topicHasLimitedViewers) {
logDebug("Post" + postName + " was not added to feed because it is private or topic has restricted audience or it is waiting for approval");
return null;
}
Node forumNode = topicNode.getParent();
Node categoryNode = forumNode.getParent();
boolean categoryHasRestrictedAudience = (hasProperty(categoryNode, EXO_VIEWER));
boolean forumHasRestrictedAudience = (hasProperty(forumNode, EXO_VIEWER));
if (categoryHasRestrictedAudience || forumHasRestrictedAudience) {
logDebug("Post" + postName + " was not added to feed because category or forum has restricted audience");
return null;
}
List<String> listContent = new ArrayList<String>();
String message = post.string(EXO_MESSAGE);
listContent.add(message);
SyndContent description = new SyndContentImpl();
description.setType("text/html");
description.setValue(getTitleRSS(message));
final String title = post.string(EXO_NAME);
final Date created = post.date(EXO_CREATED_DATE);
final String owner = post.string(EXO_OWNER);
final String linkItem = post.string(EXO_LINK);
SyndEntry entry = createNewEntry(postName, title, linkItem, listContent, description, created, owner);
return entry;
}
private SyndFeed createNewFeed(Node node, String link) throws Exception {
PropertyReader reader = new PropertyReader(node);
String desc = reader.string(EXO_DESCRIPTION, " ");
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss_2.0");
feed.setTitle(getTitleRSS(reader.string(EXO_NAME)));
feed.setPublishedDate(reader.date(EXO_CREATED_DATE, new Date()));
feed.setLink(link);
feed.setDescription(getTitleRSS(desc));
feed.setEncoding("UTF-8");
return feed;
}
private SyndEntry createNewEntry(String uri, String title, String link, List<String> listContent, SyndContent description, Date pubDate, String author) {
SyndEntry entry = new SyndEntryImpl();
entry.setUri(uri);
entry.setTitle(getTitleRSS(title));
entry.setLink(link);
entry.setContributors(listContent);
entry.setDescription(description);
entry.setPublishedDate(pubDate);
entry.setAuthor(author);
return entry;
}
private String getTitleRSS(String title) {
title = CommonUtils.decodeSpecialCharToHTMLnumber(TransformHTML.getPlainText(title));
return new StringBuilder("ST[CDATA[").append(StringEscapeUtils.unescapeHtml(TransformHTML.getTitleInHTMLCode(title,null)))
.append("END]]")
.toString();
}
public InputStream createUserRss(String userId, String link) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<SyndEntry> entries = new ArrayList<SyndEntry>();
try {
Node subscriptionNode = getUserProfileHome(sProvider).getNode(userId + "/" + Utils.FORUM_SUBSCRIOTION + userId);
PropertyReader reader = new PropertyReader(subscriptionNode);
List<String> cateIds = reader.list(EXO_CATEGORY_IDS, new ArrayList<String>());
Node node;
for (String id : cateIds) {
node = getNodeById(sProvider, id, Utils.CATEGORY);
if (node != null) {
entries.addAll(categoryUpdated(node));
}
}
List<String> forumIds = reader.list(EXO_FORUM_IDS, new ArrayList<String>());
for (String id : forumIds) {
node = getNodeById(sProvider, id, Utils.FORUM);
if (node != null && !cateIds.contains(node.getParent().getName())) {
entries.addAll(forumUpdated(node));
}
}
List<String> topicIds = reader.list(EXO_TOPIC_IDS, new ArrayList<String>());
for (String id : topicIds) {
node = getNodeById(sProvider, id, Utils.TOPIC);
if (node != null && !forumIds.contains(node.getParent().getName())) {
entries.addAll(topicUpdated(node));
}
}
} catch (PathNotFoundException e) {
LOG.info(String.format("User %s doesn't subscribe anything.", userId));
} catch (RepositoryException e) {
logDebug("Can not create feed data for user: " + userId, e);
}
try {
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss_2.0");
feed.setTitle("Forum subscriptions for " + userId);
feed.setPublishedDate(new Date());
feed.setLink(link);
feed.setDescription(" ");
feed.setEncoding("UTF-8");
feed.setEntries(entries);
SyndFeedOutput output = new SyndFeedOutput();
String s = output.outputString(feed);
s = StringUtils.replace(s, "&", "&");
s = s.replaceAll("<", "<").replaceAll(">", ">");
s = StringUtils.replace(s, "ST[CDATA[", "<![CDATA[");
s = StringUtils.replace(s, "END]]", "]]>");
return new ByteArrayInputStream(s.getBytes());
} catch (FeedException e) {
LOG.error("Can not create RSS for user: " + userId, e);
return new ByteArrayInputStream(("Can not create RSS for user: " + userId + "<br/>" + e).getBytes());
}
}
/**
* {@inheritDoc}
*/
public boolean populateUserProfile(User user, UserProfile profileTemplate, boolean isNew) throws Exception {
boolean added = false;
sessionManager.openSession();
try {
Node profile = null;
Node profileHome = getUserProfileHome();
final String userName = user.getUserName();
if (profileHome.hasNode(userName)) {
if (isNew) {
LOG.warn("Request to add user " + userName + " was ignored because it already exists.");
}
profile = profileHome.getNode(userName);
added = false;
} else {
profile = profileHome.addNode(userName, EXO_FORUM_USER_PROFILE);
added = true;
}
Calendar cal = getGreenwichMeanTime();
profile.setProperty(EXO_USER_ID, userName);
profile.setProperty(EXO_LAST_LOGIN_DATE, cal);
profile.setProperty(EXO_EMAIL, user.getEmail());
profile.setProperty(EXO_FULL_NAME, user.getDisplayName());
profile.setProperty(EXO_JOINED_DATE, cal);
if (isAdminRole(userName)) {
profile.setProperty(EXO_USER_TITLE, "Administrator");
profile.setProperty(EXO_USER_ROLE, UserProfile.ADMIN); //
} else {
profile.setProperty(EXO_USER_ROLE, UserProfile.USER); //
}
if (profileTemplate != null) {
profile.setProperty(EXO_TIME_ZONE, profileTemplate.getTimeZone());
profile.setProperty(EXO_SHORT_DATEFORMAT, profileTemplate.getShortDateFormat());
profile.setProperty(EXO_LONG_DATEFORMAT, profileTemplate.getLongDateFormat());
profile.setProperty(EXO_TIME_FORMAT, profileTemplate.getTimeFormat());
profile.setProperty(EXO_MAX_TOPIC, profileTemplate.getMaxTopicInPage());
profile.setProperty(EXO_MAX_POST, profileTemplate.getMaxPostInPage());
}
if (profileHome.isNew()) {
profileHome.getSession().save();
} else {
profileHome.save();
}
return added;
} catch (Exception e) {
LOG.error("Error while populating user profile: " + e.getMessage());
throw e;
} finally {
sessionManager.closeSession(true);
}
}
public String getLatestUser() throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node profileHome = getUserProfileHome(sProvider);
if (profileHome.hasNodes()) {
QueryManager qm = profileHome.getSession().getWorkspace().getQueryManager();
StringBuilder pathQuery = new StringBuilder();
pathQuery.append("/jcr:root").append(profileHome.getPath()).append("/element(*,exo:forumUserProfile) order by @exo:joinedDate descending");
Query query = qm.createQuery(pathQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
if (iter.getSize() > 0) {
Node node = iter.nextNode();
return node.getName();
}
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get latest user login.", e);
}
}
return "";
}
public void updateLastLoginDate(String userId) throws Exception {
sessionManager.openSession();
try {
Node userProfileHome = getUserProfileHome();
if (userProfileHome.hasNode(userId)) {
userProfileHome.getNode(userId).setProperty(EXO_LAST_LOGIN_DATE, getGreenwichMeanTime());
userProfileHome.save();
}
} finally {
sessionManager.closeSession();
}
}
//get all categories for user can view.
private List<String> getCategoriesUserCanview(Node categoryHome, List<String> listOfUser) throws Exception {
/*
* cateids = list query cateids = listinput -> public for property (null for view)
* cateids = {cateid} for private --> can not view
* cateids = new array for view --> can not view
*/
List<String> categoryCanView = new ArrayList<String>();
Map<String, List<String>> mapPrivate = getCategoryViewer(categoryHome, listOfUser, new ArrayList<String>(), new ArrayList<String>(), EXO_USER_PRIVATE);
// all categoryid public for private user
List<String> categoryIds = mapPrivate.get(Utils.CATEGORY);
// all categoryid public for Viewer
Map<String, List<String>> mapList = getCategoryViewer(categoryHome, listOfUser, null, new ArrayList<String>(), EXO_VIEWER);
List<String> categoryView = mapList.get(Utils.CATEGORY);
// user not in restricted audience or can not viewer
if (categoryIds.contains("cateId") || (categoryView != null && categoryView.isEmpty())){
return null;
}
if (categoryIds.isEmpty()) {
categoryCanView.addAll((categoryView == null ? new ArrayList<String>() : categoryView));
} else {
for (String string : categoryIds) {
if (categoryView == null || categoryView.contains(string)) {
categoryCanView.add(string);
}
}
}
return categoryCanView;
}
// check permission for everyone can view the post
private boolean postIsPublicByParent(Node postNode) throws Exception {
Node node = postNode.getParent();
// checking from the topic parent. Check by canView
if (!new PropertyReader(node).list(EXO_CAN_VIEW, Collections.EMPTY_LIST).isEmpty())
return false;
// checking from the forum parent. Check by canView
if (!new PropertyReader(node = node.getParent()).list(EXO_VIEWER, Collections.EMPTY_LIST).isEmpty())
return false;
// checking from the category parent. Check by canView
if (!new PropertyReader(node = node.getParent()).list(EXO_VIEWER, Collections.EMPTY_LIST).isEmpty())
return false;
// Check by restricted audience
if (!new PropertyReader(node).list(EXO_USER_PRIVATE, Collections.EMPTY_LIST).isEmpty())
return false;
return true;
}
// check permssion user can view
private boolean checkPermssionCanView(Node postNode, boolean isUserLogin, List<String> categoryCanView, List<String> forumCanView) throws Exception {
if(isUserLogin) {
String []path = postNode.getPath().split("/");
return (categoryCanView.isEmpty() || categoryCanView.contains(path[path.length - 4])) && (forumCanView.isEmpty() || forumCanView.contains(path[path.length - 3]));
} else {
return postIsPublicByParent(postNode);
}
}
// get post by query.
private List<Post> getPostByQuery(Node categoryHome, QueryImpl impl, int number, String userName, boolean isAdmin) throws Exception {
List<Post> list = new ArrayList<Post>();
List<String> categoryCanView = new ArrayList<String>();
List<String> forumCanView = new ArrayList<String>();
boolean isUserLogin = false;
if (!Utils.isEmpty(userName) && !UserProfile.USER_GUEST.equals(userName)) {
isUserLogin = true;
if (!isAdmin) {
List<String> listOfUser = UserHelper.getAllGroupAndMembershipOfUser(null);
categoryCanView = getCategoriesUserCanview(categoryHome, listOfUser);
if (categoryCanView == null){
return list;
}
forumCanView.addAll(getCachedDataStorage().getForumUserCanView(listOfUser, new ArrayList<String>()));
}
}
int offset = 0, count = 0, limit;
QueryResult qr;
NodeIterator iter;
Node node;
while (count < number) {
impl.setOffset(offset);
limit = number + offset;
impl.setLimit(limit);
qr = impl.execute();
iter = qr.getNodes();
if (iter.getSize() <= 0) {
return list;
}
while (iter.hasNext()) {
node = iter.nextNode();
if (isAdmin || checkPermssionCanView(node, isUserLogin, categoryCanView, forumCanView)) {
list.add(getPost(node));
count++;
if (count == number){
break;
}
}
}
offset = limit;
}
return list;
}
// the function use to get recent post for user.
public List<Post> getRecentPostsForUser(String userName, int number) throws Exception {
if (number <= 0){
return new ArrayList<Post>();
}
if (Utils.isEmpty(userName) || UserProfile.USER_GUEST.equals(userName)) {
return getNewPosts(number);
}
List<Post> list = new ArrayList<Post>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
boolean isAdmin = isAdminRole(userName);
if (!isAdmin) {
isAdmin = (new PropertyReader(getUserProfileNode(getUserProfileHome(sProvider), userName)).l(EXO_USER_ROLE, 3) == 0) ? true : false;
}
Node categoryHome = getCategoryHome(sProvider);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_POST).append(")[(");
if (!isAdmin) stringBuffer.append("(@").append(EXO_IS_APPROVED).append("='true') and (@").append(EXO_IS_HIDDEN).append("='false') and (@")
.append(EXO_IS_WAITING).append("='false') and (@").append(EXO_IS_ACTIVE_BY_TOPIC).append("='true') and ");
stringBuffer.append("(@").append(EXO_USER_PRIVATE).append("='exoUserPri' or @").append(EXO_USER_PRIVATE).append("='").append(userName)
.append("'))]").append(" order by @").append(EXO_CREATED_DATE).append(" descending");
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
// get posts
if(query instanceof QueryImpl){
list = getPostByQuery(categoryHome, (QueryImpl)query, number, userName, isAdmin);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get new post.", e);
}
}
return list;
}
//the function use to get recent post for everyone.
public List<Post> getNewPosts(int number) throws Exception {
List<Post> list = new ArrayList<Post>();
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(JCR_ROOT).append(categoryHome.getPath()).append("//element(*,").append(EXO_POST)
.append(") [((@").append(EXO_IS_APPROVED).append("='true') and (@").append(EXO_IS_HIDDEN).append("='false') and (@")
.append(EXO_IS_WAITING).append("='false') and (@").append(EXO_IS_ACTIVE_BY_TOPIC).append("='true') and (@")
.append(EXO_USER_PRIVATE).append("='exoUserPri'))] order by @").append(EXO_CREATED_DATE).append(" descending");
Query query = qm.createQuery(stringBuffer.toString(), Query.XPATH);
// get posts
if(query instanceof QueryImpl){
list = getPostByQuery(categoryHome, (QueryImpl)query, number, "", false);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to get new post.", e);
}
}
return list;
}
public boolean deleteUserProfile(String userId) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node profileHome = getUserProfileHome(sProvider);
Node profileDeleted;
Node profile = profileHome.getNode(userId);
Session session = profileHome.getSession();
profile.setProperty(EXO_USER_ROLE, UserProfile.USER_DELETED);
profile.setProperty(EXO_USER_TITLE, UserProfile.USER_REMOVED);
profile.setProperty(EXO_MODERATE_CATEGORY, new String[] {});
profile.setProperty(EXO_MODERATE_FORUMS, new String[] {});
profile.save();
StringBuilder id = new StringBuilder(userId).append(Utils.DELETED);
try {
profileDeleted = profileHome.getNode(Utils.USER_PROFILE_DELETED);
long index = profileDeleted.getNodes().getSize();
if (index > 0){
id.append(index);
}
} catch (Exception e) {
profileDeleted = profileHome.addNode(Utils.USER_PROFILE_DELETED, EXO_USER_DELETED);
session.save();
deletedUserCalculateListener(profileDeleted);
}
session.getWorkspace().move(profile.getPath(), new StringBuilder(profileDeleted.getPath()).append(CommonUtils.SLASH).append(id).toString());
try {
Node avatarHome = session.getRootNode().getNode(dataLocator.getAvatarsLocation());
if (avatarHome.hasNode(userId)) {
avatarHome.getNode(userId).remove();
}
} catch (Exception e) {
LOG.info("User deleted has not avatar !!!");
}
session.save();
} catch (PathNotFoundException e) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.exoplatform.forum.service.DataStorage#processEnabledUser(java.lang.String, java.lang.String, boolean)
*/
@Override
public void processEnabledUser(String userName, String email, boolean isEnabled) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
if (!isEnabled && !CommonUtils.isEmpty(userName)) {
processWatched(sProvider, userName);
}
//
if (!isEnabled && !CommonUtils.isEmpty(email)) {
processForumNotifyEmail(sProvider, email);
}
//
if (!CommonUtils.isEmpty(userName)) {
processUserProfile(sProvider, userName, isEnabled);
}
}
private void processUserProfile(SessionProvider sProvider, String userName, boolean isEnabled) {
try {
Node profileHome = getUserProfileHome(sProvider);
if (profileHome.hasNode(userName)) {
Node profileNode = profileHome.getNode(userName);
if (!profileNode.isNodeType(EXO_DISABLED)) {
profileNode.addMixin(EXO_DISABLED);
}
profileNode.setProperty(EXO_IS_DISABLED, !isEnabled);
profileHome.getSession().save();
} else {
LOG.warn(String.format("Forum's profile(%s) not found!", userName));
}
} catch (Exception e) {
logDebug(String.format("Process to to update status disabled/enabled of used %s is unsuccessfully.", userName), e);
}
}
/**
* Process remove userName and email, that watched by disabled user
* @param sProvider
* @param userName The userName of disabled user
*/
private void processWatched(SessionProvider sProvider, String userName) {
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_FORUM_WATCHING);
sqlQuery.append(" WHERE ").append(EXO_USER_WATCHING).append("='").append(userName).append("'");
Query query = qm.createQuery(sqlQuery.toString(), Query.SQL);
NodeIterator iter = query.execute().getNodes();
while (iter.hasNext()) {
Node watchedNode = iter.nextNode();
updateWatchedProperty(watchedNode, userName);
}
categoryHome.getSession().save();
} catch (Exception e) {
logDebug(String.format("Removes UserName %s is unsuccessfully.", userName), e);
}
}
/**
* Process remove email on forum notify.
*
* @param sProvider
* @param email The email of disabled user
*/
private void processForumNotifyEmail(SessionProvider sProvider, String email) {
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
//
StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(EXO_FORUM);
sqlQuery.append(" WHERE (").append(EXO_NOTIFY_WHEN_ADD_TOPIC).append("='").append(email).append("' OR ")
.append(EXO_NOTIFY_WHEN_ADD_POST).append("='").append(email).append("')");
Query query = qm.createQuery(sqlQuery.toString(), Query.SQL);
NodeIterator iter = query.execute().getNodes();
//
while (iter.hasNext()) {
Node forumNode = iter.nextNode();
updateForumNotifyEmail(forumNode, email);
}
categoryHome.getSession().save();
} catch (Exception e) {
logDebug(String.format("Removes email %s is unsuccessfully.", email), e);
}
}
/**
* Update two properties of Forum, that contain email of disabled user
*
* @param forumNode
* @param email
*/
private void updateForumNotifyEmail(Node forumNode, String email) {
try {
removeValueProperty(forumNode, EXO_NOTIFY_WHEN_ADD_TOPIC, email);
removeValueProperty(forumNode, EXO_NOTIFY_WHEN_ADD_POST, email);
} catch (Exception e) {
logDebug(String.format("Updated forum notify of email %s is unsuccessfully.", email), e);
}
}
/**
* Remove value of property
*
* @param node The node want to update
* @param property The property change
* @param removeValue The value will remove
* @return
* @throws Exception
*/
private int removeValueProperty(Node node, String property, String removeValue) throws Exception {
String[] values = new PropertyReader(node).strings(property, new String[] {});
int index = ArrayUtils.indexOf(values, removeValue);
if (index >= 0) {
node.setProperty(property, (String[]) ArrayUtils.remove(values, index));
}
return index;
}
/**
* Update watched properties of categories/forums/topics, that disabled user watched.
*
* @param watchedNode
* @param userName
*/
private void updateWatchedProperty(Node watchedNode, String userName) {
try {
int index = removeValueProperty(watchedNode, EXO_USER_WATCHING, userName);
if (index >= 0) {
String[] emails = new PropertyReader(watchedNode).strings(EXO_EMAIL_WATCHING, new String[] {});
watchedNode.setProperty(EXO_EMAIL_WATCHING, (String[]) ArrayUtils.remove(emails, index));
}
} catch (Exception e) {
logDebug(String.format("Updated watched user %s is unsuccessfully.", userName), e);
}
}
public void calculateDeletedUser(String userName) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
String tempUserName = userName;
userName = tempUserName.substring(0, tempUserName.indexOf(Utils.DELETED));
try {
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
String[] strs = new String[] { EXO_OWNER, EXO_MODIFIED_BY, EXO_LAST_POST_BY, EXO_USER_PRIVATE, EXO_MODERATORS, EXO_CREATE_TOPIC_ROLE,
EXO_POSTER, EXO_VIEWER, EXO_CAN_POST, EXO_CAN_VIEW, EXO_USER_WATCHING, EXO_RSS_WATCHING };
StringBuilder builder = new StringBuilder();
for (int i = 0; i < strs.length; i++) {
if (i > 0)
builder.append(" or ");
builder.append("(@").append(strs[i]).append("='").append(JCRQueryUtils.escapeSimpleQuoteCharacter(userName)).append("')");
}
StringBuilder pathQuery = new StringBuilder();
pathQuery.append(JCR_ROOT).append(categoryHome.getPath()).append("//*[").append(builder).append("]");
Query query = qm.createQuery(pathQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
while (iter.hasNext()) {
Node node = iter.nextNode();
if (node.isNodeType(EXO_FORUM_CATEGORY) || node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_TOPIC) || node.isNodeType(EXO_POST)) {
for (int i = 0; i < strs.length; i++) {
if (i < 3) {
if (new PropertyReader(node).string(strs[i], "").equals(userName)) {
node.setProperty(strs[i], tempUserName);
}
} else {
if (strs[i].equals(EXO_USER_WATCHING)) {
updateWatchedProperty(node, userName);
} else {
removeValueProperty(node, strs[i], userName);
}
}
}
}
}
if (categoryHome.isNew()) {
categoryHome.getSession().save();
} else {
categoryHome.save();
}
} catch (Exception e) {
LOG.error("Failed to calculate deleting user.", e);
}
}
public void calculateDeletedGroup(String groupId, String groupName) throws Exception {
try {
// remove forum in space
Node forumSpaceNode = getNodeById(CommonUtils.createSystemProvider(), Utils.FORUM_SPACE_ID_PREFIX + groupName, Utils.FORUM);
if (forumSpaceNode != null) {
LOG.info("\nINFO: Delete forum in space: " + forumSpaceNode.getName());
removeForum(forumSpaceNode.getParent().getName(), forumSpaceNode.getName());
}
// remove group storage in categories/forums/topics
SessionProvider sProvider = CommonUtils.createSystemProvider();
Node categoryHome = getCategoryHome(sProvider);
QueryManager qm = categoryHome.getSession().getWorkspace().getQueryManager();
String[] strs = new String[] { EXO_USER_PRIVATE, EXO_CREATE_TOPIC_ROLE, EXO_POSTER, EXO_VIEWER, EXO_CAN_POST, EXO_CAN_VIEW, EXO_MODERATORS };
StringBuilder pathQuery = new StringBuilder(JCR_ROOT).append(categoryHome.getPath()).append("//*[");
for (int i = 0; i < strs.length; i++) {
if (i > 0) {
pathQuery.append(" or ");
}
pathQuery.append("(@").append(strs[i]).append("='").append(groupId).append("') or (jcr:contains(@").append(strs[i]).append(", '").append(groupId).append("'))");
}
pathQuery.append("]");
Query query = qm.createQuery(pathQuery.toString(), Query.XPATH);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
List<String> list;
PropertyReader reader;
boolean isSave;
while (iter.hasNext()) {
Node node = iter.nextNode();
if (node.isNodeType(EXO_FORUM_CATEGORY) || node.isNodeType(EXO_FORUM) || node.isNodeType(EXO_TOPIC)) {
isSave = false;
reader = new PropertyReader(node);
for (int i = 0; i < strs.length; i++) {
list = reader.list(strs[i], new ArrayList<String>());
if (!list.isEmpty()) {
int oldSize = list.size();
list = containsGroup(list, groupId);
if(oldSize > list.size() || list.get(0).equals(CommonUtils.EMPTY_STR)) {
if(strs[i].equals(EXO_MODERATORS)) {
// calculate moderator for users
node.setProperty(EXO_TEMP_MODERATORS, reader.strings(EXO_MODERATORS, new String[]{CommonUtils.EMPTY_STR}));
node.save();
}
node.setProperty(strs[i], list.toArray(new String[list.size()]));
isSave = true;
}
}
}
if(isSave){
node.save();
}
}
}
} catch (Exception e) {
logDebug("Failed to calculate deleted Group.", e);
}
}
public static List<String> containsGroup(List<String> list, String groupId) {
List<String> ls = new ArrayList<String>();
for (String string : list) {
if(string.indexOf(groupId) >= 0) {
continue;
}
ls.add(string);
}
if(ls.isEmpty()) {
ls.add(CommonUtils.EMPTY_STR);
}
return ls;
}
public List<InitializeForumPlugin> getDefaultPlugins() {
return defaultPlugins;
}
public List<RoleRulesPlugin> getRulesPlugins() {
return rulesPlugins;
}
public Map<String, String> getServerConfig() {
return serverConfig;
}
public KSDataLocation getDataLocation() {
return dataLocator;
}
public void setDataLocator(KSDataLocation dataLocator) {
this.dataLocator = dataLocator;
sessionManager = dataLocator.getSessionManager();
repository = dataLocator.getRepository();
workspace = dataLocator.getWorkspace();
LOG.info("JCR Data Storage for forum initialized to " + dataLocator);
}
private static void logDebug(String message, Throwable e) {
LOG.warn(message);
if (LOG.isDebugEnabled() && e != null) {
LOG.debug(e.getMessage(), e);
}
}
private static void logDebug(String message) {
logDebug(message, null);
}
private Calendar getGreenwichMeanTime() {
return CommonUtils.getGreenwichMeanTime();
}
@Override
public void saveActivityIdForOwner(String ownerId, String type, String activityId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
final ReentrantLock localLock = lock;
try {
localLock.lock();
Node ownerNode = getNodeById(sProvider, ownerId, type);
ActivityTypeUtils.attachActivityId(ownerNode, activityId);
ownerNode.save();
} catch (Exception e) {
logDebug(String.format("Failed to attach activityId %s for node %s ", activityId, ownerId), e);
} finally {
localLock.unlock();
}
}
@Override
public void saveActivityIdForOwner(String ownerPath, String activityId) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
final ReentrantLock localLock = lock;
try {
localLock.lock();
Node ownerNode = getNodeAt(sProvider, ownerPath);
if(ownerNode != null) {
ActivityTypeUtils.attachActivityId(ownerNode, activityId);
ownerNode.save();
}
} catch (Exception e) {
logDebug(String.format("Failed to save attach activityId %s for node %s ", activityId, ownerPath), e);
} finally {
localLock.unlock();
}
}
@Override
public String getActivityIdForOwner(String ownerId, String type) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node ownerNode = getNodeById(sProvider, ownerId, type);
if(ownerNode != null) {
return ActivityTypeUtils.getActivityId(ownerNode);
}
} catch (Exception e) {
LOG.error(String.format("Failed to get attach activityId for %s: %s ", type, ownerId), e);
}
return null;
}
@Override
public String getActivityIdForOwner(String ownerPath) {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
Node ownerNode = getNodeAt(sProvider, ownerPath);
if(ownerNode != null) {
return ActivityTypeUtils.getActivityId(ownerNode);
}
} catch (Exception e) {
LOG.error(String.format("Failed to get attach activityId for %s ", ownerPath), e);
}
return null;
}
private StringBuilder jcrPathLikeAndNotLike(String nodeType, String fullPath) {
StringBuilder sqlQuery = new StringBuilder("SELECT * FROM ").append(nodeType)
.append(" WHERE (").append("jcr:path LIKE '").append(fullPath)
.append("/%' AND NOT jcr:path LIKE '").append(fullPath).append("/%/%'").append(")");
return sqlQuery;
}
@Override
public List<UserProfile> searchUserProfileByFilter(UserProfileFilter userProfileFilter, int offset, int limit) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
List<UserProfile> list = new ArrayList<UserProfile>();
try {
//
DataStorage storage = getCachedDataStorage();
Node userProfileNode = getUserProfileHome(sProvider);
QueryManager qm = userProfileNode.getSession().getWorkspace().getQueryManager();
QueryImpl query = (QueryImpl) qm.createQuery(buildSearchUserProfileQuery(userProfileFilter.getSearchKey()), Query.SQL);
query.setOffset(offset);
query.setLimit(limit);
QueryResult result = query.execute();
NodeIterator iter = result.getNodes();
while (iter.hasNext()) {
Node node = iter.nextNode();
list.add(storage.getQuickProfile(node.getName()));
}
} catch (Exception e) {
LOG.warn("Get UserProfile by filter failed.", e);
}
return list;
}
@Override
public int getUserProfileByFilterCount(UserProfileFilter userProfileFilter) throws Exception {
SessionProvider sProvider = CommonUtils.createSystemProvider();
try {
//
Node userProfileNode = getUserProfileHome(sProvider);
QueryManager qm = userProfileNode.getSession().getWorkspace().getQueryManager();
Query query = qm.createQuery(buildSearchUserProfileQuery(userProfileFilter.getSearchKey()), Query.SQL);
QueryResult result = query.execute();
NodeIterator iterator = result.getNodes();
return (int) iterator.getSize();
} catch (Exception e) {
LOG.warn("Get count of UserProfile by filter failed.", e);
}
return 0;
}
private String buildSearchUserProfileQuery(String searchKey) {
String fullPath = "/" + dataLocator.getUserProfilesLocation();
StringBuilder sqlQuery = jcrPathLikeAndNotLike(Utils.USER_PROFILES_TYPE, fullPath);
if (Utils.isEmpty(searchKey) == false) {
searchKey = searchKey.replace("*", "%");
sqlQuery.append(" AND (")
.append(EXO_USER_ID).append(" LIKE '%").append(searchKey).append("%' OR ")
.append(EXO_FULL_NAME).append(" LIKE '%").append(searchKey).append("%' OR ")
.append(EXO_SCREEN_NAME).append(" LIKE '%").append(searchKey).append("%'")
.append(")");
}
sqlQuery.append(" AND (").append(EXO_IS_DISABLED).append(" IS NULL OR ")
.append(EXO_IS_DISABLED).append("<>'true')");
return sqlQuery.toString();
}
@Override
public void removeCacheUserProfile(String userName) {
}
private NodeIterator getNodeIteratorBySQLQuery(SessionProvider sProvider, String sqlQuery, int offset, int limit, boolean caseInsensitiveOrder) throws Exception {
QueryManager qm = sessionManager.getSession(sProvider).getWorkspace().getQueryManager();
QueryImpl query = (QueryImpl) qm.createQuery(sqlQuery, Query.SQL);
if (limit > 0) {
query.setOffset(offset);
query.setLimit(limit);
}
if (caseInsensitiveOrder) {
query.setCaseInsensitiveOrder(true);
}
QueryResult result = query.execute();
return result.getNodes();
}
}